正确的Singleton Pattern Objective C(iOS)? [英] Correct Singleton Pattern Objective C (iOS)?

查看:97
本文介绍了正确的Singleton Pattern Objective C(iOS)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网上发现了一些使用GCD创建单例类的信息。这很酷,因为它的线程安全,开销很低。遗憾的是,我找不到完整的解决方案,只能找到sharedInstance方法的片段。所以我使用试错法制作了自己的课程 - 以及等等 - 以下内容:

  @implementation MySingleton 

// MARK: -
// MARK:使用GCD的单一模式

+(id)allocWithZone:(NSZone *)zone {return [[self sharedInstance]保留]; }
- (id)copyWithZone:(NSZone *)zone {return self; }
- (id)autorelease {return self; }
- (oneway void)release {/ *单身人士无法释放* /}
- (void)dealloc {[super dealloc]; / *永远不应该被称为* /}
- (id)retain {return self; }
- (NSUInteger)retainCount {return NSUIntegerMax; / *那是soooo非零* /}

+(MySingleton *)sharedInstance
{
static MySingleton * instance = nil;

静态dispatch_once_t谓词;
dispatch_once(& predicate,^ {
// ---调用super避免了上述allocWithZone
实例的死锁= [[super allocWithZone:nil] init];
});

返回实例;
}

// MARK: -
// MARK:初始化

- (id)init
{
self = [超级初始化];
if(self)
{
//这里的初始化代码。
}
返回自我;
}

@end

请随时评论和告诉我,如果我遗漏了某些东西或做了一些完全错误的事情;)



干杯
Stefan

  +(instancetype)sharedInstance 
{
static dispatch_once_t pred;
static id sharedInstance = nil;
dispatch_once(& pred,^ {
sharedInstance = [[self alloc] init];
});
返回sharedInstance;
}

- (无效)dealloc
{
//实施-dealloc&重构
//非单例使用时删除abort()。
abort();
}

就是这样。覆盖保留发布 retainCount ,其余的只是隐藏错误并添加一堆不必要的代码。每行代码都是等待发生的错误。实际上,如果要在共享实例上调用 dealloc ,则应用程序中存在非常严重的错误。该bug应该被修复,而不是隐藏。



这种方法也适用于重构以支持非单例使用模式。几乎所有存在于单个版本之后的单例最终都会被重构为非单例形式。一些(如 NSFileManager )继续支持单例模式,同时也支持任意实例化。



注意上面也是ARC中的正常工作。


I found some information in the net to create a singleton class using GCD. Thats cool because it's thread-safe with very low overhead. Sadly I could not find complete solutions but only snippets of the sharedInstance method. So I made my own class using the trial and error method - and et voila - the following came out:

@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

Please feel free to comment and tell me if I've missing something or doing something completely wrong ;)

Cheers Stefan

解决方案

Keep it simple:

+(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();
}

That is it. Overriding retain, release, retainCount and the rest is just hiding bugs and adding a bunch of lines of unnecessary code. Every line of code is a bug waiting to happen. In reality, if you are causing dealloc to be called on your shared instance, you have a very serious bug in your app. That bug should be fixed, not hidden.

This approach also lends itself to refactoring to support non-singleton usage modes. Pretty much every singleton that survives beyond a few releases will eventually be refactored into a non-singleton form. Some (like NSFileManager) continue to support a singleton mode while also supporting arbitrary instantiation.

Note that the above also "just works" in ARC.

这篇关于正确的Singleton Pattern Objective C(iOS)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆