bla*_*acx 29 singleton objective-c grand-central-dispatch ios
我在网上找到了一些信息来创建一个使用GCD的单例类.这很酷,因为它的线程安全,开销很低.遗憾的是,我找不到完整的解决方案,只能找到sharedInstance方法的片段.所以我使用试错法制作了自己的课 - 而且瞧瞧 - 以下内容出来了:
@implementation MySingleton
// MARK: -
// MARK: Singleton Pattern using GCD
+ (id)allocWithZone:(NSZone *)zone { return [[self sharedInstance] retain]; }
- (id)copyWithZone:(NSZone *)zone { return self; }
- (id)autorelease { return self; }
- (oneway void)release { /* Singletons can't be released */ }
- (void)dealloc { [super dealloc]; /* should never be called */ }
- (id)retain { return self; }
- (NSUInteger)retainCount { return NSUIntegerMax; /* That's soooo non-zero */ }
+ (MySingleton *)sharedInstance
{
static MySingleton * instance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
// --- call to super avoids a deadlock with the above allocWithZone
instance = [[super allocWithZone:nil] init];
});
return instance;
}
// MARK: -
// MARK: Initialization
- (id)init
{
self = [super init];
if (self)
{
// Initialization code here.
}
return self;
}
@end
Run Code Online (Sandbox Code Playgroud)
如果我遗漏了某些东西或做了一些完全错误的事情,请随时发表评论并告诉我;)
干杯斯蒂芬
bbu*_*bum 82
把事情简单化:
+(instancetype)sharedInstance
{
static dispatch_once_t pred;
static id sharedInstance = nil;
dispatch_once(&pred, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (void)dealloc
{
// implement -dealloc & remove abort() when refactoring for
// non-singleton use.
abort();
}
Run Code Online (Sandbox Code Playgroud)
这就对了.重写retain,release,retainCount和剩下的只是隐藏错误和加入一些不必要的行代码.每行代码都是等待发生的错误.实际上,如果要导致dealloc在共享实例上调用,则应用程序中存在非常严重的错误.那个bug应该修复,而不是隐藏.
这种方法也适用于重构以支持非单例使用模式.几乎所有存在于单个版本之后的单例最终都会被重构为非单例形式.一些(像NSFileManager)继续支持单例模式,同时也支持任意实例化.
请注意,上述内容在ARC中也"正常工作".
Jan*_*ano 19
// See Mike Ash "Care and Feeding of Singletons"
// See Cocoa Samurai "Singletons: You're doing them wrong"
+(MySingleton *)singleton {
static dispatch_once_t pred;
static MySingleton *shared = nil;
dispatch_once(&pred, ^{
shared = [[MySingleton alloc] init];
shared.someIvar = @"blah";
});
return shared;
}
Run Code Online (Sandbox Code Playgroud)
请注意,dispatch_once不是可重入的,因此从dispatch_once块内部调用自身会使程序死锁.
不要试图对自己进行防御性编码.如果你没有编写框架代码,请将你的类视为正常,然后坚持上面的单例习语.把单身成语想象成一种方便的方法,而不是你班级的定义特征.您希望在单元测试期间将您的类视为普通类,因此可以保留可访问的构造函数.
不要打扰使用 allocWithZone:
alloc.Objective-C中不再使用内存区域,因此allocWithZone:只保留与旧代码的兼容性.NSAllocateObject()和创建更多实例class_createInstance().单件工厂方法始终返回以下三种类型之一:
id 指示返回类型未完全知晓(您正在构建类集群的情况).instancetype 表示返回的类型是封闭类的实例. MySingleton在示例中)保持简单.自从你标记了这个iOS以来,替换单例是将ivar保存到app委托,然后使用一个方便的宏,如果你改变主意你可以重新定义:
#define coreDataManager() \
((AppDelegate*)[[UIApplication sharedApplication] delegate]).coreDataManager
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25139 次 |
| 最近记录: |