fuz*_*oat 1 iphone cocoa objective-c
我对这段代码(在CocoaFundamentals指南中提供)有点困惑,它在创建单例实例时会覆盖一些方法.
static id sharedReactor = nil;
+(id)sharedInstance {
if(sharedReactor == nil) sharedReactor = [[super allocWithZone:NULL] init];
return sharedReactor;
}
Run Code Online (Sandbox Code Playgroud)
.
+(id)allocWithZone:(NSZone *)zone {
return[[self sharedInstance] retain];
}
-(id)retain {
return self;
}
Run Code Online (Sandbox Code Playgroud)
在创建单例实例的代码中,+ sharedInstance方法从超类(在我的例子中是NSObject)中调用[super allocWithZone:NILL]上面的allocWithZone仅在您尝试使用它来创建新单例时才被调用.
我感到困惑的是使用retain,尤其是看到retain也被覆盖以返回self.任何人都可以解释这个,不管怎么说都写不出来:
+(id)allocWithZone:(NSZone *)zone {
return [self sharedInstance];
}
-(id)retain {
return self;
}
Run Code Online (Sandbox Code Playgroud)
EDIT_001:
根据评论和阅读网上的各种帖子,我决定采用以下内容(见下文)我选择采用共享单例方法,如果需要,我可以选择创建第二个或第三个实例.同样在这个阶段,因为我只使用单例作为MVC的模型部分用于简单的iPhone应用程序,所以我决定将线程安全性排除在外.我知道它很重要,随着我越来越熟悉iPhone编程,我可能会使用+ initialize(记住它可以被调用两次的子类问题)另外我添加了一个dealloc,首先要记录一条消息应该是单例被释放,但如果不再需要单身人士,也要妥善清理.
@interface SharedManager : NSObject
+(id)sharedInstance;
@end
@implementation SharedManager
static id myInstance = nil;
+(id)sharedInstance {
if(myInstance == nil) {
myInstance = [[self alloc] init];
}
return myInstance;
}
-(void)dealloc {
NSLog(@"_deal: %@", [self class]);
[super dealloc];
myInstance = nil;
}
@end
Run Code Online (Sandbox Code Playgroud)
在测试中我发现我在dealloc中将静态变量设置为nil,或者它保持其指向原始对象的指针.我最初对此有点困惑,因为我期望静态的范围是实例,我猜它是相反的类,这是有道理的.
欢呼加里
首先,不要使用此代码.几乎没有理由为一个简单的单身人士做这一切.Apple正在展示一个"强迫单身人士",因为它不可能创造出两个.真的很需要这个.您几乎总是可以使用大多数具有单例构造函数的Cocoa对象使用的"共享单例"方法.
这是我实现共享单例的首选方法:
+ (MYManager *)sharedManager
{
static MYManager *sharedManager = nil;
if (sharedManager == nil)
{
sharedManager = [[self alloc] init];
}
return sharedManager;
}
Run Code Online (Sandbox Code Playgroud)
而已.不需要其他代码.使用的呼叫者+sharedManager将获得共享实例.呼叫的呼叫者+alloc可以创建唯一的实例,如果他们真的想要.这就是如此着名的"单身人士"如何NSNotificationCenter工作.如果您真的想要自己的私人通知中心,那么该课程没有理由禁止它.这种方法具有以下优点:
+alloc不会遇到令人惊讶的"远距离的怪异行为"行为,这需要他知道对象的内部实现细节.如果你真的需要一个强制单例,因为有问题的对象映射到一个无法共享的唯一资源(并且很少遇到这种情况),那么你仍然不应该使用+alloc技巧来强制执行它.这只是掩盖了尝试创建新实例的编程错误.相反,您应该以这种方式捕获编程错误:
+ (MYManager *)sharedManager
{
static MYManager *sharedManager = nil;
if (sharedManager == nil)
{
sharedManager = [[self alloc] initSharedManager];
}
return sharedManager;
}
- (id)init
{
NSAssert(NO, @"Attempting to instantiate new instance. Use +sharedManager.");
return nil;
}
// Private method. Obviously don't put this in your .h
- (id)initSharedManager
{
self = [super init];
....
return self;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1089 次 |
| 最近记录: |