实例化单例类
我创建了一个单例类来跟踪我的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
几乎在所有情况下,单例的一点是你不关心谁首先实例化它。谁是第一个打电话给[Something sharedSomething]
的人将是创作者。你想要使用“How do I implement an Objective-C singleton that is compatible with ARC?”中给出的模式,它将确保单例只创建一次。
这可能是最简单的方法:
static MyClass* theInstance = nil;
+ (MyClass*) sharedInstance {
@synchronized(self) {
if (! theInstance) {
theInstance = [[MyClass alloc] init];
}
}
return theInstance;
}
...所以在您要访问的单身地方,你只是做[MyClass sharedInstance]
以便获得对该实例的参考。
请注意,这不会防止人们在您的单例类中手动调用alloc
和init
来创建其他实例。如果您需要这样做,您可以以类似于上述的方式实施init
,以防止使用alloc
和init
创建/返回其他实例。然而,在实践中,单身人士课程最常使用sharedInstance
方法(有时候在名称上有微小的变化,如[UIApplication sharedApplication]
)。
我推荐在http://stackoverflow.com/questions/7568935/how-do-i-implement-an-objective-c-singleton-that-is-compatible-with-arc回答中给出的GCD模式。 @synchronize解决方案的价格要高一些,而且自从添加dispatch_once以来,没有理由支付这些费用。 – 2012-04-11 00:52:49
两种方法都可以,是的。我个人更喜欢'@ synchronized';我只是觉得它更具可读性。 – aroth 2012-04-11 00:55:57
单身人士通常懒惰地实例化 - 第一次访问时,实例被创建并从访问方法返回。随后对访问方法的调用仅返回已创建的实例。
标准模式是:1.锁定或以其他方式使以下线程安全(即dispatch_once()
)。 2.检查单实例是否已经创建。 3.如果没有,创建它。 4.释放锁定(如果适用)。 5.返回实例。
如果您因某种原因需要创建实例,则可能会出现这种情况。当类被添加到运行时时,运行时会发送类方法+load
,该运行时在应用程序执行的早期阶段。 (+initialize
看起来也是一个候选人 - 它在运行时正好在类接收到它的第一个(其他)消息之前发送(不包括+load
) - 但它实际上并没有给你任何东西,因为它会被发送紧接在您发送sharedInstance
之前。)
gcc __constructor__
function attribute也可以工作(在clang中也是如此),尽管被记录为未针对ObjC实施。具有此属性的函数将在输入main()
之前调用。不过,我不太确定这个选项的内存管理含义。运行时应该全部设置好,但是不会有autorelease池。
这里非常有用的技巧。 '+ load'是一个非常有用的工具,可以知道(尽管你经常不需要它)。 – 2012-04-11 00:54:12
通常单类实例化被访问的第一次:
static SomeClass *_instance = nil;
+ (SomeClass *) instance {
@synchronized(self) {
if (!_instance)
_instance = [[self alloc] init];
}
return _instance;
}
我使用此代码实例单身。GCD需要同步的护理
+ (SingletonClass *)sharedInstance {
static SingletonClass *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[SingletonClass alloc] init];
sharedInstance.property = [Property new];
});
return sharedInstance;
}
看看这个:http://stackoverflow.com/questions/145154/what-does-your-objective-c-singleton-look-like – 2012-04-11 00:46:12
或这样的:HTTP:// stackoverflow.com/questions/7568935/how-do-i-implement-an-objective-c-singleton-that-is-compatible-with-arc – 2012-04-11 00:47:03
链接似乎是关于实施一个单身人士。我已经有了我的书面和运作。我在我的一个类中的一个IBAction中实例化它,但是我很困惑我是否应该在别处实例化它以便它是全局的? – TopChef 2012-04-11 00:49:17