使用allocWithZone返回静态

时间:2012-03-06 16:56:42

标签: objective-c

根据Big Nerd Ranch指南对iOS编程的想法,我试图以下列方式定义singleton对象:

@implementation ImageStore

static ImageStore *defaultImageStore = nil;

- (id)init
{
    if (defaultImageStore) {
        return defaultImageStore;
    }

    self = [super init];
    if (self) {
        dictionary = [[NSMutableDictionary alloc] init];
    }

    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter addObserver:self selector:@selector(clearCache) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];

    return self;
}

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

+ (ImageStore *)defaultImageStore
{
    if (!defaultImageStore) {
        defaultImageStore = [[super allocWithZone:NULL] init];
    }
    return defaultImageStore;
}

这很好用,但是分析器抱怨allocWithZone,说

  

具有+0保留计数的对象返回给调用者,其中预期+1(拥有)保留计数

我认为代码只是欺骗分析器并且发生的事情是正常的,但有没有更好的模型来做我想做的事情?

2 个答案:

答案 0 :(得分:2)

我不打扰所有这些东西。这是我的模式:

@implementation MyClass

-(id) init { ... } /* normal init */

+(MyClass*) defaultMyClass
{
    static MyClass* theObject = nil;
    @synchronized([MyClass class])  // remove synchronzed block in single threaded app
    {
        if (theObject == nil)
        {
            theObject = [[self alloc] init];
        }
    }
    return theObject;
}

可能您可以在类扩展中隐藏初始化程序,以便记录您不应该使用它。

还有GCD方法(下面是从Rob Napier的链接中窃取的),它实际上更轻量级。

+ (id) defaultMyClass
{
    static dispatch_once_t pred;
    static MyClass* theObject = nil;

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

我一直抵制GCD模式,因为在我看来,它看起来不那么明显。但是,这没有什么不能通过评论修复!与@synchronized相比,GCD使用的锁更轻,所以这会更快。

答案 1 :(得分:0)

正如我在评论中提到的,解决编译器警告就像在语句中添加一个保留一样简单,这在Apple doc中提到。

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

旁注:我没有提到这个,但我正在为iOS开发,发现dispatch_once方法似乎暂停了我的应用程序的执行。