实例化单例类

时间:2012-04-11 00:44:01

标签: iphone objective-c cocoa-touch

我创建了一个单例类来跟踪我的iPhone应用程序上的数据。我知道singleton只需要实例化一次,但实例化它的最佳位置是什么?应该在appDelegate中完成吗?我希望能够从众多类中调用此单例(包含NSMutableArray),以便我可以访问该数组。

这是我写的课程:

#import "WorkoutManager.h"

static WorkoutManager *workoutManagerInstance;

@implementation WorkoutManager
@synthesize workouts;

+(WorkoutManager*)sharedInstance {
    if(!workoutManagerInstance) {
        workoutManagerInstance = [[WorkoutManager alloc] init];
    }
    return workoutManagerInstance;
}

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

@end

5 个答案:

答案 0 :(得分:6)

在几乎所有情况下,单身人士的观点是你不关心谁首先实例化它。无论谁是第一个致电[Something sharedSomething]的人都将成为创造者。您想要使用“How do I implement an Objective-C singleton that is compatible with ARC?”中给出的模式。它将确保仅创建一次单例。

答案 1 :(得分:2)

单身人士通常懒惰地实例化 - 第一次访问它们时,实例将从访问方法创建并返回。对访问方法的后续调用只返回已创建的实例。

标准模式是:1。锁定或以其他方式使线程安全(即dispatch_once())。 2.检查是否已创建单个实例。 3.如果没有,请创建它。 4.释放锁定(如果适用)。 5.返回实例。

如果由于某种原因需要,可以提前创建实例。当类被添加到运行时时,运行时将发送类方法+load,这是应用程序执行的早期阶段。 (+initialize似乎也是候选者 - 它是在课程收到第一个(其他)消息(也不包括+load)之前由运行时发送的 - 但它实际上并没有让你任何事情,因为它会在您发送sharedInstance之前立即发送。)

gcc __constructor__ function attribute也有效(尽管也是如此),尽管记录为没有为ObjC实施。在输入main()之前,将调用具有此属性的函数。不过,我不太清楚这个选项对内存管理的影响。应该全部设置运行时,但是还没有自动释放池。

答案 2 :(得分:1)

这可能是最简单的方法:

static MyClass* theInstance = nil;

+ (MyClass*) sharedInstance {
    @synchronized(self) {
        if (! theInstance) {
            theInstance = [[MyClass alloc] init];
        }
    }

    return theInstance;
}

...所以在你想要访问单例的地方,你只需要[MyClass sharedInstance]来获得对实例的引用。

请注意,这不会阻止人们在您的单例类上手动调用allocinit来创建其他实例。如果您需要这样做,您可以采用与上述类似的方式实施init,以防止使用allocinit创建/返回其他实例。

然而,在实践中,单身类最常使用sharedInstance方法(有时在命名方面有微小变化,例如[UIApplication sharedApplication])。

答案 3 :(得分:0)

通常在第一次访问单例类时实例化它们:

static SomeClass *_instance = nil;

+ (SomeClass *) instance {
    @synchronized(self) {
        if (!_instance)
            _instance = [[self alloc] init];
    }
    return _instance;
}

答案 4 :(得分:0)

我正在使用此代码来实例化单例。 GCD负责同步

+ (SingletonClass *)sharedInstance {
  static SingletonClass *sharedInstance;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[SingletonClass alloc] init];
    sharedInstance.property = [Property new];
  });
  return sharedInstance;
}