Immer, wenn ich eine Methode in meinem eigenen Code implementiere, die Objekte von mehr als einer Klasse akzeptieren oder zurückgeben kann, versuche ich immer die spezifischste Oberklasse zu verwenden. Wenn ich zum Beispiel eine Methode implementieren würde, die abhängig von ihrer Eingabe ein NSArray * oder ein NSDictionary * zurückgibt, würde ich dieser Methode den Rückgabetyp NSObject * geben, da dies die direkteste gemeinsame Oberklasse ist. Hier ein Beispiel:Warum (ID) in einer Methodensignatur verwenden, wenn (NSObject *) genauer wäre?
@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
ich viele Fälle in Foundation und andere APIs, wo Apple-Anwendungen (id) in bestimmten Methodensignaturen, wenn (NSObject *) wären genauer bemerkt habe. Zum Beispiel ist hier ein Verfahren zur Herstellung NSPropertyListSerialization:
+ (id)propertyListFromData:(NSData *)data
mutabilityOption:(NSPropertyListMutabilityOptions)opt
format:(NSPropertyListFormat *)format
errorDescription:(NSString **)errorString
Die möglichen Rückgabetypen von dieser Methode sind NSData, NSString, NSArray, NSDictionary, NSDate und NSNumber. Es scheint mir, dass ein Rückgabetyp von (NSObject *) eine bessere Wahl wäre als (id), da der Aufrufer dann in der Lage wäre, NSObject-Methoden wie Retain ohne eine Typumwandlung aufzurufen.
Ich versuche generell, die Idiome zu kopieren, die von den offiziellen Frameworks eingeführt werden, aber ich mag auch zu verstehen, was sie motiviert. Ich bin mir sicher, dass Apple in solchen Fällen einen gültigen Grund für die Verwendung von (id) hat, aber ich sehe es einfach nicht. Was vermisse ich?
NSProxy ist kein NSObject. NSObject ist nicht die einzige Root-Klasse, daher ist es keine sichere Annahme, dass alles eine Unterklasse davon ist. –