2014-04-04 52 views
11

假裝我對NSObject的類別定義以下方法:爲什麼dot語法不能用於返回類型爲instancetype的方法?

+ (instancetype)allocTemplate 
{ 
    id instance = [self new]; 

    return instance; 
} 

,我有下面的類:

@interface FDActor : NSObject 

@property (nonatomic, copy) NSString *name; 

+ (void)sayHi;  

@end 


@implementation FDActor 

+ (void)sayHi 
{ 
    [self allocTemplate].name; 
} 

@end 

如何在編譯時來[self allocTemplate].name錯誤了,如果自己是FDActor?

我知道它的作品,如果您使用正常的消息發送語法,但我明確感興趣的點語法錯誤。

+0

什麼是錯誤?我嘗試了類似的東西,並將其編譯。 –

+0

在'id'類型的對象上找不到屬性'name'。只是要明確我並不是要用「FDActor」代替「自我」。我的意思是在FDActor內的類方法內調用該方法。 –

+0

如果該類別在NSObject上,那麼不會將instancetype返回類型爲NSObject的東西嗎? – michaels

回答

3

它看起來好像instancetype僅用於分配期間的類型檢查,所以 FDActor *actor = [FDActor allocTemplate]不會產生警告。

如果我們施放allocTemplate的返回類型,問題就會消失。

- (void)sayHi { ((__typeof__(self))[[self class] allocTemplate]).name; }

但要注意,因爲將typeof在實例方法這隻能一個實例是另一個實例。還要注意,因爲我們現在明確地鍵入了返回值,所以allocTemplate方法不再是必需的,如果所有人都在尋找類型檢查,那麼我們甚至可以只投出零,它將工作。

如果我們嘗試在一個類的方法同樣的事情,這是行不通的

+ (void)sayHi { ((__typeof__(self) *)[self allocTemplate]).name; } 這是因爲(__typeof__(self) *)實幹家不能計算爲FDActor *Class *這ARC會抱怨。看起來好像沒有辦法在編譯時從類方法中以通用方式解析類型信息FDActor *

我寧可期待instancetype關鍵字稍微有用。

1

錯誤消息告訴你。 [self allocTemplate]id。屬性語法從不適用於id

注意,這確實工作:

[FDActor allocTemplate].name; 

我認爲類到instancetype是必須在調用中指定有關;否則我們只能回到id

+0

我明白這一點,但什麼是那麼instancetype呢? –

+0

http://nshipster.com/instancetype/ – matt

+1

對不起,我不是說我不知道​​什麼樣的實例類型。我的意思是,如果實例類型被視爲所有方法的ID或針對它所調用的點語法屬性,那麼它的意義何在。實例類型的重點在於它被識別爲稱爲方法的任何類的類型。我想要對方法調用進行類型檢查,而不僅僅是分配。 –

0

我會對此進行一番嘗試,但我並不完全理解instancetype支持是如何實現的,更不用說編譯器類型檢查系統的所有細節。換句話說,這是我最好的猜測,而不是一個權威的或完整的答案......

編譯後,Objective-C方法實際上是函數,其中self是該函數的第一個參數,並鍵入id。所以,你必須:這裏由+allocTemplate返回值的類型的

void sayHi(id self, SEL _cmd) 
{ 
    [self allocTemplate].name; // Actually calls to objc_msgSend, but that doesn't matter here 
} 

編譯器的處理似乎與此有關。如果您將自己更改爲明確的FDActor,則錯誤消失。當然,對於方法 - 與屬性相反 - 編譯器按照您的預期輸入self,並且會警告(或者在ARC下出現錯誤)自我看起來不會響應的方法。看起來這可能是編譯器檢查instancetype上下文中可用方法與屬性的區別(bug?)。

相關問題