[英]Singleton in Objective C (Non-ARC)
我发现了如何在目标c(Non-ARC)中实现单例。
// AppTools.h in my code
@interface AppTools : NSObject {
NSString *className;
}
@property ( nonatomic, retain ) NSString *className;
+ ( id ) sharedInstance;
@end // AppTools
// AppTools.m in my code
static AppTools *sharedAppToolsInstance = nil;
@implementation AppTools
@synthesize className;
- ( id ) init {
self = [ super init ];
if ( self ) {
className = [ [ NSString alloc ] initWithString: @"AppTools" ];
}
return self;
} // init
- ( void ) dealloc {
// Should never be called, but just here for clarity really.
[ className release ];
[ super dealloc ];
} // dealloc
+ ( id ) sharedInstance {
@synchronized( self ) {
if ( sharedAppToolsInstance == nil )
sharedAppToolsInstance = [ [ super allocWithZone: NULL ] init ];
}
return sharedAppToolsInstance;
} // sharedInstance
+ ( id ) allocWithZone: ( NSZone * )zone {
return [ [ self sharedInstance ] retain ];
} // allocWithZone:
- ( id ) copyWithZone: ( NSZone * )zone {
return self;
} // copyWithZone:
- ( id ) retain {
return self;
} // retain
- ( unsigned int ) retainCount {
return UINT_MAX; // denotes an object that cannot be released
} // retainCount
- ( oneway void ) release {
// never release
} // release
- ( id ) autorelease {
return self;
} // autorelease
我想知道如何在sharedInstance方法中使用allocWithZone:。 在此,allocWithZone:方法的接收者为“ super”,“ super”为NSObject。 尽管返回值是NSObject实例,但它被替换为sharedInstance。
那么className的存储空间在哪里? 我不知道如何处理这部分代码。
预先感谢。
我认为您发布的代码很难用于创建单例。
在我的所有项目中,我都使用以下代码来使用单例。 它非常简单,线程安全并且可以完美运行:
+ (CustomClass *)shared
{
static CustomClass *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[CustomClass alloc] init];
});
return singleton;
}
而且我相信您可以在ARC和非ARC项目中使用它。
更新:如注释中所述,它实际上是shared object
而不是singleton
因为可以创建更多特定类的实例。 但这已经足够接近了。
我认为,如果您不是在编写开源代码/库,而没有其他人会使用它,那么使用共享库并将它们视为单例可能会容易得多。
我使用与Nekto相同的代码,但singleton = [[CustomClass alloc] init];
应该是singleton = [[self alloc] init];
。
想象一个子类CustomSubclass
。 如果你打电话
CustomSubclass *sharedObject = [CustomSubclass shared];
您将不会获得CustomSubclass
而是CustomClass
。
您问“那么className的存储空间在哪里?”
大多数类本身并不实现alloc
或allocWithZone
,而是依赖于从NSObject
继承的实现。 NSObject
实现分配原始调用类的对象。
因此,在您的示例AppTools
确实覆盖了allocWithZone
,此实现通过对super
的调用来调用NSObject
的allocWithZone
,而NSObject
的方法执行实际分配并返回AppTools
类型的对象。
[注意:如果您想知道NSObject
的实现如何知道要分配哪种对象,那么这很简单-调用继承的方法不会更改方法的self
参数, alloc
/ allocWithZone
是类方法,而self
参数是类方法本身引用类对象(而不是类的实例对象)。]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.