且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

单例方法中的确定类名

更新时间:2023-11-13 13:44:34

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

You can use id within the method, to avoid referencing the actual class name, and then specify an instancetype return type so that the compiler knows that what is being returned is an instance of this particular class:

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






警告语:通过以这种方式实现它,您可能会陷入一种错误的安全感,即现在可以成功地将该类继承为子类。


A word of warning: By implementing it this way, you can be lulled into a false sense of security that this class can now successfully be subclassed.

但这实际上有问题。但是,如果您有两个不同的子类,则现在只有一个共享的单例(除非您在两个子类中都覆盖了 sharedManager )。

But this actually has problems. But if you have two different subclasses of this class, you now only have a single shared singleton (unless you override sharedManager in both of the subclasses).

例如,假设您有该类的两个子类, SubClass1 SubClass2

For example, let's imagine you had two subclasses of this class, SubClass1 and SubClass2:

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

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

在这种情况下, shared2 不会返回 Subclass2 的实例,因为 sharedMyManager 静态是您为其调用 sharedManager 的第一个子类。因此, shared2 会令人困惑地返回由 [SubClass1 sharedManager] 实例化的先前实例。

In this case, shared2 will not return an instance of Subclass2, because the static of sharedMyManager will be of the first subclass for which you called sharedManager. Thus shared2 will confusingly return that previous instance that was instantiated by [SubClass1 sharedManager].

由于这个原因,有人建议您避免使用这种 instancetype / id 模式,因为它建议一定程度的安全子类化,这实际上会在这类奇怪的边缘情况下引起问题。因此,许多人认为您应该在 sharedManager 中引用实际的类名。

For this reason, some people suggest that you avoid this instancetype/id pattern, because it suggests a degree of safe subclassing which really can cause problems in these sorts of curious edge-cases. Because of this, many will argue that you should reference the actual class names within sharedManager.

实际上,我承认我仍然在代码段中使用此 instancetype / id 模式来简化单例的创建,但是只需注意此限制即可。

As a practical matter, I confess that I still use this instancetype/id pattern in a code snippet to facilitate easy creation of singletons, but just be aware of this limitation.