【发布时间】:2012-10-19 12:59:47
【问题描述】:
init 方法是在 NSObject 类中声明的,因此客户端代码可以创建我的单例类的新实例,有什么方法可以实现真正的单例,使客户端无法创建新实例。
【问题讨论】:
-
你应该看看Peter Hosey's blog post这个话题。他的实现是一个“真正的”单例。
标签: objective-c ios cocoa-touch
init 方法是在 NSObject 类中声明的,因此客户端代码可以创建我的单例类的新实例,有什么方法可以实现真正的单例,使客户端无法创建新实例。
【问题讨论】:
标签: objective-c ios cocoa-touch
这样做:
static SingletonClass *singleton;
+ (SingletonClass *)sharedInstance
{
@synchronized(self) { //For thread safety
if (singleton == nil) {
[[self alloc] init];
}
return singleton;
}
}
-(id)init
{
if (singleton) { //This way init will always return the same instance
return singleton;
}
self = [super init];
if (self) {
singleton = self;
}
return singleton;
}
【讨论】:
[[SingletonClass alloc] init],您将泄漏一个实例。您需要在返回singleton 之前丢弃传递给init 的self 实例,或者覆盖allocWithZone: 以返回共享实例,这样它就是传递给init 的实例。
self 曾经进入自动释放池,那么 ARC 需要做一些认真的工作。
这是在目标 c 中做单例的正确方法
+ (id)sharedManager
{
static dispatch_once_t onceQueue;
static SingletonObjectClass *singleton = nil;
dispatch_once(&onceQueue, ^{
singleton = [[self alloc] init];
});
return singleton;
}
- (id)init {
self = [super init];
if (self) {
//.....
}
return self;
}
【讨论】:
alloc另一个客户。
init 方法用于初始化实例变量。本身不会创建对象。需要重写 alloc、copy 方法才能实现真正的单吨。
希望这应该澄清。
+ (id)alloc {
NSLog(@"%@: use +sharedInstance instead of +alloc", [[self class] name]);
return nil;
}
+ (id)new {
return [self alloc];
}
+ (SingletonClass *)sharedInstance {
static SingletonClass *myInstance = nil;
if (!myInstance)
{
myInstance = [[super alloc] init];
}
return myInstance;
}
【讨论】:
您可以每次返回一个类的静态对象,使其成为单例。
@implementation Singleton
@synthesize testVar;
+ (Singleton*) sharedObject {
static Singleton * myInstance = nil;
if (myInstance == nil) {
myInstance = [[[self class] alloc] init];
testVar = 5;
// Set default values if needed
return myInstance;
}
访问对象及其成员:
[[Singleton sharedObject] testVar]
【讨论】: