单例方法中的明确类名

时间:2015-12-03 05:54:10

标签: objective-c design-patterns singleton

以下是单例方法的示例代码:

$a = json_decode($data);
"Update tableName set".$a->col1." =20......."

有没有办法摆脱某个类名声明+ (id)sharedManager { static MyManager *sharedMyManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedMyManager = [[self alloc] init]; }); return sharedMyManager; } 并将其替换为MyManager *self *等抽象类型?

1 个答案:

答案 0 :(得分:2)

您可以在方法中使用id,以避免引用实际的类名,然后指定instancetype返回类型,以便编译器知道返回的是此特定的实例类:

+ (instancetype)sharedManager {
    static id sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

警告:通过这种方式实现它,你可能会陷入虚假的安全感,这个类现在可以成功地被子类化了。

但实际上这有问题。但是如果你有这个类的两个不同的子类,你现在只有一个共享的单例(除非你在两个子类中重写sharedManager)。

例如,假设您有两个此类的子类SubClass1SubClass2

SubClass1 *shared1 = [SubClass1 sharedManager];
SubClass2 *shared2 = [SubClass2 sharedManager];

NSLog(@"%@", shared1);
NSLog(@"%@", shared2);

在这种情况下,shared2不会返回Subclass2的实例,因为static的{​​{1}}将是您调用{{1}的第一个子类}}。因此sharedMyManager会混淆地返回由sharedManager实例化的先前实例。

出于这个原因,有些人建议你避免使用这种shared2 / [SubClass1 sharedManager]模式,因为它表明了一定程度的安全子类化,它确实会在这些奇怪的边缘案例中引起问题。因此,许多人会争辩说你应该引用instancetype中的实际类名。

实际上,我承认我仍然在代码段中使用这个id / sharedManager模式来促进单例的轻松创建,但只是要注意这个限制。