簡體   English   中英

為什么在類方法BAD中“self = [[Rectangle alloc] init]”?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM