以下是单例方法的示例代码:
$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 *
等抽象类型?
答案 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
)。
例如,假设您有两个此类的子类SubClass1
和SubClass2
:
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
模式来促进单例的轻松创建,但只是要注意这个限制。