私はコンパイルしないで書き込んだコアデータ検証メソッドを持っています。メソッドをコンパイルしてコンパイルできるようにすることはできますが、実行時エラーが発生します。このメソッドの2つのバージョンは次のとおりです(2番目のバージョンでは「*」が見つからないことに注意してください)。このバージョンは、(以下警告およびエラーを参照)コンパイラの警告やエラーを与える(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;
}
「:認識されないセレクタークラス0x7fff70a448e8に送ら+ [NSCFNumberのdoubleValue]」このバージョンは、ランタイムエラーがコンパイルしかし与えます
コンパイラのエラーと警告:私は最終的に問題は呼び出し元のコードであってもよいことを考え出し
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"];
}
initialValueの前に '&'を使用するように呼び出し元を変更し、メソッドの最初のバージョンを使用し、すべてが機能しました。だから、新しい呼び出し元のコードは、1つの行は、このように変更されました:
[self validateValue:&initialValue forKey:@"initialValue" error:nil];
しかし、それは「&」を持っている必要が本当にあります? setPrimitiveInitialValueは '&'を使用しません。私はObjective-Cの理解がまだ十分に進んでいないように感じています。あなたが知っているすべての人は、非常に単純な答えでこれを些細な疑問に思うでしょう。
その他'id *'の意味を説明しました。 Objective-Cオブジェクトの最初のフィールドがそのクラスオブジェクトへのポインタであるということを、ランタイムエラーが発生した理由を追加したいと思います。だから '(id *)value'として' initialValue'を渡し、 '[* value doubleValue]'を呼び出すと '[* initialValue doubleValue]'となり、あるオブジェクト/構造体へのポインタはポインタと同じですその最初のフィールドに渡すので、実際には*クラスのdoubleValueを呼び出しています* NSCFNumber - クラスメソッドを示す実行時エラーの+記号に注目してください。 –