을 사용하는 이유(id)방법에 서명할 때(nsobject 의*)이상이 될 것입 정확?

StackOverflow https://stackoverflow.com/questions/1829028

  •  11-09-2019
  •  | 
  •  

문제

때마다 나를 구현하는 방법에서 나의 자신의 코드를 받아 들일 수있는 반환 또는 개체의 하나 이상의 클래스,항상 사용하려고 가장 특정 수퍼 클래스를 사용할 수 있다.예를 들어,만약 내가 하려고 했을 구현하는 메소드를 반환할 수 있습 있기 때문입*나 NSDictionary*에 따라 입력하는 방법이익 유형의 nsobject 의*,이후의 가장 직접적인 공통 수퍼 클래스.예를 들어 다음과 같습니다.

@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

나는 것으로 나타났 많은 경우 재단에서와는 다른 Api 를 사용(id)에서 특정 메서드 서명을 때(nsobject 의*)는 것이 더 정확합니다.예를 들어,다음의 방법 NSPropertyListSerialization:

+ (id)propertyListFromData:(NSData *)data 
          mutabilityOption:(NSPropertyListMutabilityOptions)opt 
                    format:(NSPropertyListFormat *)format 
          errorDescription:(NSString **)errorString

익 가능한 유형에서 이 방법은 NSData,@입,있기 때문입,NSDictionary,NSDate 및 NSNumber.그것은 보인다는 것을 나에게 반환의 유형(nsobject 의*)는 것보다 더 나은 선택이 될(id)이후 호출자는 다음을 호출 할 수 있 nsobject 의 방법을 통한 유지하지 않고 형식이다.

나는 일반적으로 모방하려고의 관용구에 의해 설립 된 공식적인 프레임워크,그러나 나는 또 이해하는 것을 좋아 그렇게 하는 이유는 무엇입니까.나는 사과는 일부에 대 한 유효한 이유를 사용하여(id)이 같은 경우에,그러나 나는 보지 않습니다.나는 무엇이 없는가?

도움이 되었습니까?

해결책

ID를 사용하면 컴파일러에게 알려지지 않은 유형의 객체가됩니다. nsObject를 사용하면 컴파일러를 사용하면 nsObject에서만 사용할 수있는 메시지 만 사용해야합니다. 따라서 ... 배열이 반환되었고 ID로 캐스팅되면 Compiler 경고없이 ObjectAtIndex를 호출 할 수 있습니다. nsobject의 캐스트와 함께 돌아 오는 반면, 당신은 경고를받을 것입니다.

다른 팁

메소드 선언에서 (ID)가 사용되는 이유는 두 배입니다.

(1) 방법은 모든 유형을 취하거나 반환 할 수 있습니다. nsarray에는 임의의 객체가 포함되어 있으므로 objectAtIndex: 임의의 유형의 객체를 반환합니다. 캐스팅 NSObject* 또는 id <NSObject> 두 가지 이유로 부정확합니다. 첫째, 배열은 특정 작은 메소드 세트를 구현하는 한 비 NSObject 서브 클래스를 포함 할 수 있으며, 둘째, 특정 반환 유형에는 캐스팅이 필요합니다.

(2) Objective-C는 공분산 선언을 지원하지 않습니다. 고려하다:

@interface NSArray:NSObject
+ (id) array;
@end

이제 전화 할 수 있습니다 +array 둘 다 NSArray 그리고 NSMutableArray. 전자는 불변의 배열을 반환하고 후자는 돌연변이 가능한 배열을 반환합니다. Objective-C의 공분산 선언 지원 부족으로 인해 위의 것이 반환으로 선언 된 경우 (NSArray*), 서브 클래스 방법의 클라이언트는`(nsmutableArray*)에 캐스트해야합니다. 추악하고 연약하고 오류가 발생하기 쉽습니다. 따라서 일반 유형을 사용하는 것은 일반적으로 가장 간단한 솔루션입니다.

따라서 ... 특정 클래스의 인스턴스를 반환하는 메소드를 선언하는 경우 TypEcast를 명시 적으로 명시 적으로 선언하십시오. 재정의 된 메소드를 선언하는 경우 하위 클래스를 반환 할 수 있습니다. 그리고 서브 클래스를 반환한다는 사실은 클라이언트에 노출 된 다음 사용합니다. (id).

버그를 제출할 필요가 없습니다. 이미 여러 가지가 있습니다.


OBJC는 이제 instancetype 예어.

NSArray'S +배열 방법은 이제 다음과 같이 선언 할 수 있습니다.

+ (instancetype) array;

그리고 컴파일러는 처리 할 것입니다 [NSMutableArray array] 반환으로 NSMutableArray* 동안 [NSArray array] 돌아 오는 것으로 간주됩니다 NSArray*.

캐스팅없이 ID의 포인터에서 이미 호출 할 수 있습니다. 특정 슈퍼 클래스 유형을 사용하는 경우 컴파일러 경고를 피하기 위해 서브 클래스 메소드를 호출 할 때마다 포인터를 시전해야합니다. 컴파일러가 귀하에게 경고하지 않고 의도를 더 잘 나타내도록 ID를 사용하십시오.

(id)또한 종종에 반환하기 위해 사용하는 개체를 수의 하위 더 쉽게입니다.예를 들어,이니셜라이저하고 편리한 방법을 반환,(id)의미하는 모든 서브 클래스가 없을 재정의 수퍼 클래스의 메소드는 특정한 요구가 있는 경우가 아니면 그렇게 할 이유.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top