我有一個我寫的不會編譯的核心數據驗證方法。我可以修改該方法,以便編譯...但後來我得到運行時錯誤。該方法的兩個版本如下(注意在第二個版本中缺少'*')。這個版本的編譯,但給人的運行時錯誤「+ [NSCFNumber的doubleValue]:無法識別的選擇發送到類0x7fff70a448e8」:將消息發送到(id *)變量或使用(id *)參數的正確方法
- (BOOL)validateInitialValue:(id *)value error:(NSError **)error {
if (*value == nil) {
return YES;
}
if ([*value doubleValue] < 0.0) {
return NO;
}
return YES;
}
這個版本提供了編譯器警告和錯誤(見警告和錯誤如下):
- (BOOL)validateInitialValue:(id *)value error:(NSError **)error {
if (value == nil) {
return YES;
}
if ([value doubleValue] < 0.0) {
return NO;
}
return YES;
}
編譯器錯誤和警告:
warning: Semantic Issue: Receiver type 'id *' is not 'id' or interface pointer, consider casting it to 'id'
warning: Semantic Issue: Method '-doubleValue' not found (return type defaults to 'id')
error: Semantic Issue: Invalid operands to binary expression ('id' and 'double')
我終於想通這個問題可能是在調用代碼:
- (void)setInitialValue:(NSNumber *)initialValue {
[self willChangeValueForKey:@"initialValue"];
[self validateValue:initialValue forKey:@"initialValue" error:nil];
[self setPrimitiveInitialValue:initialValue];
[self didChangeValueForKey:@"initialValue"];
}
我更改爲使用「&」來電初值前和使用的方法的第一個版本,和一切工作。因此,新調用的代碼具有一行變化是這樣的:
[self validateValue:&initialValue forKey:@"initialValue" error:nil];
但是否真正有必要對「&」? setPrimitiveInitialValue不使用'&'。我覺得我對Objective-C的理解還不夠完善,你所有的專家都會發現這是一個微不足道的問題,並帶有非常直接的答案。
其他已經解釋了'id *'的含義;我只想補充一點,你得到運行時錯誤的原因是Objective-C對象的第一個字段是指向它的類對象的指針。所以當你傳遞'initialValue'作爲'(id *)的值,然後調用'[* value doubleValue]',那就是'[* initialValue doubleValue]',並且指向某個對象/結構的指針與指針相同到它的第一個字段,所以你實際上在* class * NSCFNumber上調用doubleValue - 注意運行時錯誤中的+號,它表示一個類方法。 –