Singleton对象的CFArrayRef问题无效

时间:2011-04-07 14:48:52

标签: iphone objective-c singleton nsarray

我已经构建了一个单例对象来管理我的应用程序中的一些数据

@interface MyCommon : NSObject {

    NSArray *quizz;
    int iCurrentQuestion;

};

+ (MyCommon *)singleton;

@property (retain) NSArray *quizz;
@property (assign) int iCurrentQuestion;

@end

MyCommon.m

#import "MyCommon.h"


// MyCommon.m:
@implementation MyCommon

static MyCommon * MyCommon_Singleton = nil;


@synthesize iCurrentQuestion;

+ (MyCommon *)singleton
{
    if (nil == MyCommon_Singleton)
    {
        MyCommon_Singleton = [[MyCommon alloc] init];
        NSLog(@"allocating MyCommon_Singleton at %@",MyCommon_Singleton);
    }
    else {

        NSLog(@"accessing singleton : %@", MyCommon_Singleton);
    }

    return MyCommon_Singleton;
}


- (NSArray*) getQuizz{

    return quizz;
}

- (void) setQuizz:(NSArray *)array {

    quizz = [NSArray arrayWithArray:array];

    NSLog(@"setQuizz : %@",quizz);    
}

编写quizz对象(setQuizz)没有问题,但是当我尝试访问它进行阅读时,我遇到了崩溃:quizz看起来无效,Xcode通知我一个无效的CFArrayRef

我不知道我的代码有什么问题。

2 个答案:

答案 0 :(得分:2)

您为quizz提供了自定义设置器,但它不符合声明属性的方式。

当您设置新值时,您不会保留quizz。它可能会在之后发布,当您访问它时会导致崩溃。

你应该写

- (void)setQuizz:(NSArray *)array {
    if (quizz != array) {
        NSArray *tmp = quizz;
        quizz = [array retain]; // retain the new value
        [tmp release]; // release the old one
    }
    NSLog(@"setQuizz : %@",quizz);
}

答案 1 :(得分:0)

这比代码需要更多的代码。首先,如果你要提供自己的方法,你应该在@property声明中声明你没有。你也没有正确地保留你的变量。另外,你应该使用dispatch_once()来获得线程安全&快速保证单身人士的方法只创造一次。

@interface MyCommon : NSObject {}

@property(nonatomic, retain) NSArray *quiz;
@property (assign) int iCurrentQuestion;

+ (MyCommon *)singleton;

@end

@implementation MyCommon

@synthesize quiz;
@synthesize iCurrentQuestion;

-(id)init {
    self = [super init];
    if(self) {
        quiz = [[NSMutableArray alloc init];
        iCurrentQuestion = 0;
    }
    return self;
}

+ (MyCommon *)singleton {
    static MyCommon *singleton = nil;
    static dispatch_once_t pred;

    dispatch_once(&pred, ^{
        singleton = [[MyCommon alloc] init];
    });
    return singleton;
}

@end

然后你就做了

[MyCommon singleton].quiz = //some array