複数のクラスのオブジェクトを受け入れるか返すメソッドを独自のコードで実装するときは、常に最も特定のスーパークラスを使用しようとします。たとえば、入力に応じてNSArray *またはNSDictionary *を返すメソッドを実装しようとした場合、そのメソッドはNSObject *の戻り型になります。なぜなら、それは最も直接的な共通スーパークラスなのでです。ここでは例です:(NSObject *)がより正確になる場合、なぜメソッドシグネチャで(id)を使用するのですか?
@interface MyParser()
- (BOOL)stringExpressesKeyValuePairs:(NSString *)string;
- (BOOL)stringExpressesAListOfEntities:(NSString *)string;
- (NSArray *)parseArrayFromString:(NSString *)string;
- (NSDictionary *)parseDictionaryFromString:(NSString *)string;
@end
@implementation MyParser
- (NSObject *)parseString:(NSString *)string {
if ([self stringExpressesKeyValuePairs:string]) {
return [self parseDictionaryFromString:string];
}
else if ([self stringExpressesAListOfEntities:string]) {
return [self parseArrayFromString:string];
}
}
// etc...
@end
私は(NSObjectの*)は、より正確になり、アップルの用途(ID)は、特定のメソッドのシグネチャで財団と他のAPIの多くの例を気づきました。例えば、ここでNSPropertyListSerializationの方法です:
+ (id)propertyListFromData:(NSData *)data
mutabilityOption:(NSPropertyListMutabilityOptions)opt
format:(NSPropertyListFormat *)format
errorDescription:(NSString **)errorString
この方法から可能な戻り値の型はNSDataの、NSStringの、NSArrayの、NSDictionaryの、NSDate、およびのNSNumberです。呼び出し元は、型キャストなしでretainのようなNSObjectメソッドを呼び出せるため、(NSObject *)の戻り型が(id)よりも良い選択となるようです。
私は一般的に正式なフレームワークによって確立されたイディオムをエミュレートしようとしますが、私はそれらの動機付けを理解したいと思っています。私はAppleがこのような場合に(ID)を使用するいくつかの正当な理由があると確信していますが、私はそれを見ていないだけです。私は何が欠けていますか?
NSProxyはNSObjectではありません。 NSObjectは唯一のルートクラスではないので、すべてがそのサブクラスになるという安全な前提はありません。 –