1

*間違いなく休憩が必要です... 原因は単純です - 配列が割り当てられていませんでした... 助けてくれてありがとう。その恥ずかしい間違いのために、私はそれを削除するために私の投稿にフラグを立てました. ユーザーにとって役に立たないと思います;)*

iOS でシングルトン クラスを作成しようとしましたが、おそらく間違いを犯しています。コード (ARC は必須ではありません):

#import "PeopleDatabase.h"
#import "Person.h"

#import <Foundation/Foundation.h>

@interface PeopleDatabase : NSObject{objetive
    NSMutableArray* _arrayOfPeople;
}

+(PeopleDatabase *) getInstance;

@property (nonatomic, retain) NSMutableArray* arrayOfPeople;


@end

--

    @implementation PeopleDatabase
    @synthesize arrayOfPeople = _arrayOfPeople;

    static PeopleDatabase* instance = nil;

    -(id)init{
        if(self = [super init]) {
            Person* person = [[[Person alloc] initWithName:@"John" sname:@"Derovsky" descr:@"Some kind of description" iconName:@"johnphoto.png" title:Prof] retain];

            [_arrayOfPeople addObject:person];
            NSLog(@"array count = %d", [_arrayOfPeople count]); // <== array count = 0 
            [person release];
        }
        return self;
    }

    +(PeopleDatabase *)getInstance {
        @synchronized(self)
        {
            if (instance == nil)
                NSLog(@"initializing");
                instance = [[[self alloc] init] retain];
                NSLog(@"Address: %p", instance);
        }
        return(instance);
    }

    -(void)dealloc {

        [instance release];
        [super dealloc];
    }
@end

次のように getInstance を呼び出す場合:

PeopleDatabase *database = [PeopleDatabase getInstance];
NSLog(@"Adress 2: %p", database);

アドレス 2 の値は getInstance と同じ値です。

4

6 に答える 6

25

シングルトンを作成する標準的な方法は次のようなものです...

Singleton.h

@interface MySingleton : NSObject

+ (MySingleton*)sharedInstance;

@end

Singleton.m

#import "MySingleton.h"

@implementation MySingleton

#pragma mark - singleton method

+ (MySingleton*)sharedInstance
{
    static dispatch_once_t predicate = 0;
    __strong static id sharedObject = nil;
    //static id sharedObject = nil;  //if you're not using ARC
    dispatch_once(&predicate, ^{
        sharedObject = [[self alloc] init];
        //sharedObject = [[[self alloc] init] retain]; // if you're not using ARC
    });
    return sharedObject;
}

@end
于 2013-03-13T11:07:42.403 に答える
2
    @synchronized(self)
    {
        if (instance == nil)
            NSLog(@"initializing");
            instance = [[[self alloc] init] retain];
            NSLog(@"Address: %p", instance);
    }

ifそのステートメントの括弧が欠落しているようです。書かれているように、唯一異なるinstance == nilのはログメッセージを出力することです。

于 2013-03-13T11:09:57.033 に答える
2

シングルトン インスタンスの作成方法については、次の Apple ドキュメントを確認してください。

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html

于 2013-03-13T11:06:11.750 に答える
1

Web を読んで個人的に練習した後、現在のシングルトンの実装は次のとおりです。

@interface MySingleton

@property myProperty;
+(instancetype) sharedInstance;

@end


@implementation MySingleton

+ (instancetype) sharedInstance
{
    static dispatch_once_t pred= 0;
    __strong static MySingleton *singletonObj = nil;
    dispatch_once (&pred, ^{
        singletonObj = [[super allocWithZone:NULL]init];
        singletonObj.myProperty = initialize ;
    });

    return singletonObj;
}

+(id) allocWithZone:(NSZone *)zone
{
    return [self sharedInstance];
}

-(id)copyWithZone:(NSZone *)zone
{
    return self;
}

これはスレッドセーフな実装であり、クラスで「alloc init」を呼び出すことによって新しいオブジェクトを作成するリスクを回避します。属性の初期化は、同様の理由で「init」オーバーライド内ではなく、ブロック内で発生する必要があります。

于 2014-10-06T20:47:06.917 に答える
0

この関数では、+(PeopleDatabase *)getInstance中括弧を正しく配置する必要があると思います:このように

+(PeopleDatabase *)getInstance {
    @synchronized(self)
    {
        if (instance == nil)
        {
            NSLog(@"initializing");
            instance = [[[self alloc] init] retain];
            NSLog(@"Address: %p", instance);
        }
        return instance ;
    }
}
于 2013-03-13T11:12:22.483 に答える
0

これは、常に中かっこの後に if と else を使用するという、規則正しくない規則によって回避できるエラーです。

+(PeopleDatabase *)getInstance {
    @synchronized(self)
    {
        if (instance == nil)
            NSLog(@"initializing");
            instance = [[[self alloc] init] retain];
            NSLog(@"Address: %p", instance);
    }
    return(instance);
}

instance が nil の場合、次のステートメントのみが実行されます。そして、それは nslog であり、割り当てではありません。その後、以前に使用されたかどうかに関係なく、インスタンスがとにかく割り当てられます。これにより、呼び出しごとに新しいシングルトンが提供されます。漏れの原因となるところで。

+(PeopleDatabase *)getInstance {
    @synchronized(self)
    {
        if (instance == nil) {
            NSLog(@"initializing");
            instance = [[[self alloc] init] retain];
            NSLog(@"Address: %p", instance);
        }
    }
    return(instance);
}

しかし、デバッグ中にこのエラーが発生しました。混乱するかもしれませんが、元の問題は解決しません。alloc と init を追加して_arrayOfPeople、同様に保持してください。

-(id)init{
    if(self = [super init]) {
        Person* person = [[[Person alloc] initWithName:@"John" sname:@"Derovsky" descr:@"Some kind of description" iconName:@"johnphoto.png" title:Prof] retain];

        _arrayOfPeople = [[[NSMutableArray alloc] init] retain]; //dont forget the release
        [_arrayOfPeople addObject:person];
        NSLog(@"array count = %d", [_arrayOfPeople count]); // <== array count = 1 !!!  
        [person release];
    }
    return self;
}

あなたのコードでは _arrayOfPeople は nil であり、 addObject は nil に送信されますが、これは中止を引き起こしませんが、何もしません。次に、count が nil に送信され、0/nil が返されます。

于 2013-03-13T11:23:50.613 に答える