2013-05-11 82 views
0

我正在通過一些Cocoa教程,並且運行這個語法並且不知道它的含義。從上下文中我假設你爲變量設置了強類型。什麼「ID <someType> variableName」是什麼意思在Objective-C

id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section]; 
    return [sectionInfo name]; 

我發現,通過移除<someType>語法仍然允許我發送[sectionInfo name]消息。所以很明顯,編譯器認識到id處的對象仍然是適當的類型,無論如何。

Link to tutorial.

+0

在Objective-C中,類型爲「id」的變量意味着它所保存的對象可以是* any * Objective-C類的一個實例,因此您可以調用** any **方法,編譯器不會抱怨。 – Greg 2013-05-12 04:32:28

+0

此外,在任何情況下,Objective-C都不是**強類型語言,因此甚至像'NSNumber * a = @「Hello」; NSArray * b = a; [(NSMutableDictionary *)b setObject:@「asdf」forKey:@「something」];'會編譯,儘管有警告,只會在您嘗試在未實現的對象上調用setObject:forKey時崩潰該方法。 – Greg 2013-05-12 04:35:09

回答

3
id sectionInfo; 

這意味着sectionInfo是任何類的一個實例。它將在沒有任何警告的情況下響應編譯器可見的任何地方聲明的任何方法(這就是爲什麼要避免使用類型id)。

id <NSFetchedResultsSectionInfo> sectionInfo; 

此聲明sectionInfo只響應(也許 - 有些可能是@optional)在NSFetchedResultsSectionInfo協議聲明的方法。正如你發現的那樣,試圖調用任何其他方法會產生一個警告。

更好的聲明將是這樣的:

MySpecificClass<NSFetchedResultsSectionInfo> *sectionInfo; 

此聲明sectionInfo實現協議NSFetchedResultsSectionInfoMySpecificClass(或子類)的實例。編譯器將允許在NSFetchedResultsSectionInfo協議中的任何特定於該類(或超類)任何方法的方法調用。

+1

在這種情況下,當然,你不能用'MySpecificClass'聲明,因爲你從UIKit接收一個對象,並且這個特定的類是私有的。但是,如果可以的話,你當然應該申報班級。 – 2013-05-12 03:27:27

+0

不完全正確,@ BrentRoyal-Gordon。你絕對正確的是,變量定義的特異性比API所暗示的更具體。不幸的是,在Objective-C中這是必須的,因爲在許多地方''(id)'類型泄漏到API中。因此,我們必須在我們的設計中應用紀律,並在我們的代碼中大量散佈'assert([returnObject isKindOfClass:...])''。 – bbum 2013-05-12 07:26:08

+0

謝謝bbum。現在完美。 – zaner 2013-05-14 17:05:20

3

這意味着VARIABLENAME可以是任何種類的類構成,但具有執行SOMETYPE協議

+0

差不多。看到我的答案。 tl; dr編譯器將'id'類型的協議視爲*只允許來自協議的方法*,這與不協議的'id'聲明不同。 – bbum 2013-05-12 00:09:09