[英]Why is “self = [[Rectangle alloc] init]” in a class method BAD?
在Apple的“Objective-C Programming Language”文檔中,第48頁說:
+ (Rectangle *)rectangleOfColor:(NSColor *) color
{
self = [[Rectangle alloc] init]; // BAD
[self setColor:color];
return self;
}
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[Rectangle alloc] init]; // GOOD
[newInstance setColor:color];
return newInstance;
}
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[self alloc] init]; // EXCELLENT
[newInstance setColor:color];
return newInstance;
}
一個是壞的,一個是好的,另一個是優秀的。 這是為什么?
還有第四種模式......
(1)類型不匹配是BAD。
(2)靜態引用類產生的方法在子類中不能正常運行
(3)對類的動態引用意味着子類將被實例化為子類實例
(4)
+ (instancetype)rectangleOfColor:(NSColor *)color // Über-bestest evar!
{
Rectangle *newInstance = [[self alloc] init];
[newInstance setColor:color];
return newInstance;
}
llvm添加了instancetype
關鍵字,表示“喲!這個方法返回它被調用的任何類的實例”。 因此,如果你是上面的子類,你可以:
RectangleSub *rs = [RectangleSub rectangleOfColor:[NSColor paisleyColor]];
但這會警告(超出可怕的顏色選擇):
RectangleSub *rs = [Rectangle rectangleOfColor:[NSColor puceColor]];
而(id)返回類型在第二種情況下不會發出警告。
請注意,我還將聲明的newInstance
切換為顯式類型為Rectangle*
。 這也更好,因為在該方法的上下文中 , newInstance
只能被安全地視為Rectangle*
。
+ (Rectangle *)rectangleOfColor:(NSColor *) color
{
self = [[Rectangle alloc] init]; // BAD
[self setColor:color];
return self;
}
在類方法中, self
指的是類,而不是它的實例對象。
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[Rectangle alloc] init]; // GOOD
[newInstance setColor:color];
return newInstance;
}
如果Rectangle將被子類化(MyFancyRectangle),那么仍然會返回一個普通的Rectangle對象
+ (id)rectangleOfColor:(NSColor *)color
{
id newInstance = [[self alloc] init]; // EXCELLENT
[newInstance setColor:color];
return newInstance;
}
將返回MyFancyReactangle
好象叫喜歡MyFancyReactangle *r = [MyFancyReactangle rectangleOfColor:[UIColor redColor]]
為[self alloc]
被稱為上sublass。 注意,這里再次調用self
,因為+alloc
是一個類方法。
出於同樣的原因,所有init…
和方便的創建者方法都應該返回id
。 它允許子類返回子類的對象,而不會讓編譯器發瘋。
在第一種情況下,您指定self
指針(它應指向Rectangle
類對象)的實例Rectangle
。 這絕對不正確。
在第二種情況下,您需要對要實例化的類進行硬編碼 - 在這種情況下為Rectangle
。
在第三種情況下,您允許類的標識來確定實例的類,而不是在代碼中明確指定它。 然后,如果您的Dodecahedron
類需要使用相同的代碼,則不需要更改類名。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.