둘 이상의 클래스의 객체를 받아들이거나 반환 할 수있는 코드를 구현할 때마다 항상 가장 구체적인 수퍼 클래스를 사용하려고합니다. 예를 들어, 입력에 따라 NSArray * 또는 NSDictionary *를 반환 할 수있는 메서드를 구현하려는 경우 해당 메서드는 NSObject *의 반환 형식을 제공합니다.이 메서드는 가장 직접적인 일반 수퍼 클래스이므로 NSObject *의 반환 형식을 지정합니다. 나는 특정 메소드 서명 애플의 용도 (ID)가 (NSObject의 *)이 더 정확한 것 재단과 다른 API의 많은 경우를 발견했습니다(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
예를 들면 다음과 같습니다이다. 예를 들어, 다음 NSPropertyListSerialization하는 방법이다 :이 방법에서
+ (id)propertyListFromData:(NSData *)data
mutabilityOption:(NSPropertyListMutabilityOptions)opt
format:(NSPropertyListFormat *)format
errorDescription:(NSString **)errorString
가능한 반환 형식이있는 NSData,있는 NSString, NSArray를,있는 NSDictionary,있는 NSDate와의 NSNumber이다. 호출자가 타입 캐스팅없이 retain과 같은 NSObject 메소드를 호출 할 수 있기 때문에 (NSObject *)의 리턴 타입이 (id)보다 더 나은 선택이 될 것 같습니다.
나는 일반적으로 공식 프레임 워크에 의해 설정된 관용구를 모방하려고하지만, 나는 또한 무엇이 그들을 동기 부여 하는지를 알고 싶다. 애플은 이런 경우에 (id)를 사용하는 몇 가지 유효한 이유가 있다고 확신하지만, 나는 그것을 보지 않고있다. 내가 뭘 놓치고 있니?
NSProxy는 NSObject가 아닙니다. NSObject는 유일한 루트 클래스가 아니므로 모든 것이 그 서브 클래스가된다는 것은 안전한 가정이 아닙니다. –