我剛剛發現了一些令我有點困惑的東西,不知有人會爲我澄清這件事。ID沒有警告?
NSArray *nextArray = [NSArray arrayWithObjects:@"ONE", @"TWO", @"THREE", nil];
for(id eachObject in nextArray) {
NSLog(@"COUNT: %d", [eachObject length]);
}
爲什麼上述內容不會抱怨/警告我正在詢問身份證的長度這一事實?
我剛剛發現了一些令我有點困惑的東西,不知有人會爲我澄清這件事。ID沒有警告?
NSArray *nextArray = [NSArray arrayWithObjects:@"ONE", @"TWO", @"THREE", nil];
for(id eachObject in nextArray) {
NSLog(@"COUNT: %d", [eachObject length]);
}
爲什麼上述內容不會抱怨/警告我正在詢問身份證的長度這一事實?
當您不需要編譯器類型檢查時,您可以使用id
。您可以發送任何消息到id
類型而不發出警告,並且您可以將id
分配給任何其他類型,而不進行類型轉換。
這允許您從數組中取出一個對象而不使用轉換。例如,你可以自由地假設數組包含NSString的:
NSString* someString = [myArray objectAtIndex:1];
它也可以讓你將消息發送到一個對象而澆注或者警告。實際上,您希望發送的消息可能不是任何正式類別或協議的一部分:
id someObject = [myArray objectAtIndex:1];
if ([someObject respondsToSelector:@selector(setName:)])
{
[someObject setName:@"Foo"];
}
編譯器永遠不會輸入發送給ID的檢查消息。這部分是Objective-C的活力所在。
如果eachObject是任何其他類型,那麼如果編譯器無法解析方法名稱,則會發生錯誤。
Objective-C中的每個對象都知道它有什麼類,它是否可以處理消息。編譯器不是檢查類,它是運行時的對象本身。
對象的類可以在compilertime時未定義,但是在運行時每個對象都有一個定義的類。
簡單地說,id表示所有的Objective-C類。所以,它的長度方法它屬於一個NSString類。編譯器不會向您發出警告。 id在運行時動態確定,在編譯時未知。
In Objective-C id
是任何類型對象的普通類型,不管類是什麼類型的,都可以用於類的實例和類對象本身。 id
類型完全是非限制性它沒有關於對象的信息,除了它是一個對象。所以編譯器無法知道該對象是否可以響應某個方法,因爲它不知道它是什麼類型的對象。 通過在你的代碼中使用它,你基本上會說'不管這是指向什麼,執行這個操作'。
的NSArray
可能包含不同的對象類型,例如:
NSArray *thArray = [[NSArray alloc] initWithObjects:@"Stack",@"Overflow",[NSNumber numberWithInt:10],nil];
for(id theObject in thArray) {
NSLog(@"COUNT: %lu", [theObject length]);
}
的id
可以表示任何對象(在此情況下NSString
或NSNumber
),
爲此編譯器不能知道原始的方法length
是否存在。
因爲(id)可能是任何NSObject。就像一個可以有長度的NSString。 – Popeye 2012-08-01 16:53:23
@Popeye:甚至不需要是NSObject。可以繼承NSProxy,或者一些完全不同的基類。儘管在實踐中,幾乎所有東西都至少符合NSObject協議。 – 2012-08-01 16:59:15
我看到了,我知道id可以是任何Objective-C類,但我一直認爲你必須在嘗試訪問它之前檢查類型並進行投射。非常感激。 – fuzzygoat 2012-08-01 17:00:20