2017-02-06 16 views
4

버그입니까? 아니면 여기에 약간의 교훈이 있습니까?NSNumber가 mutableCopy에 긍정적으로 응답합니까?

NSNumber *someNumber = @(1); 
[someNumber respondsToSelector:@selector(mutableCopy)]; // returns YES (!) 
[someNumber respondsToSelector:@selector(mutableCopyWithZone:)]; // returns NO 

애플 LLVM 7.1 (아이폰 OS SDK 9.3)

이상한

답변

5

NSObject 자체가 (-mutableCopyWithZone:으로 호출하여 (모든 개체, 심지어 NSCopying 또는 NSMutableCopying을 준수하지 않는) -mutableCopy를 구현하기 때문이다 있도록 NSMutableCopying 그냥 -mutableCopy의 구현을 반복 할 필요없이 -mutableCopyWithZone:을 구현하기 위해 얻을 구현하는 것). NSObject에서 상속

모든 -mutableCopy에 응답하지만, 실제로 그것을라고하면 NSNumber-mutableCopyWithZone:에 응답하지 않기 때문에, 그것은 충돌 것입니다.

당신은

assert([NSObject instanceMethodForSelector:@selector(mutableCopy)] == [NSNumber instanceMethodForSelector:@selector(mutableCopy)]) 

bbum의 분석이 볼 수 꽤 잘 요약 - 동적으로 이러한 검사를 할 때 당신은 전혀 기대하지 않습니다 답변을 얻을 수 있기 때문에 미묘한 가장자리 경우가 있습니다.

+1

세부 정보를 보내 주셔서 감사합니다. – bbum

+1

좋은 정보. NSObject의 문서를 살펴 본다면 다음과 같습니다. NSMutableCopying 프로토콜을 채택한 클래스에 대한 편리한 메소드입니다. mutableCopyWithZone에 대한 구현이 없으면 예외가 발생합니다.. –

+0

@BenFlynn 하하, 저는 겨우 반이 자신을 기억합니다. 이것은 코드 나 문서에서 쉽게 발견 할 수있는 기능이 아닙니다. –

4

. 나는 그 클래스가 -mutableCopy을 구현할 것을 기대하지 않을 것이다. 태그가있는 포인터 구현에서 낙오 할 수 있습니다. 그렇다면 @ (REALLYBIGNUMBERTHATISNEARMAX)가 동작을 변경합니다.

미묘한 교훈은 일반적인 기능 테스트에 실제로 respondsToSelector:을 사용할 수 없다는 것입니다. isKindOfClass:도 사용할 수 없습니다. 그것이 실패 할 많은 상황이 있습니다 (NSArrayNSMutableArray은 매우 이상하게 행동하는 데 사용됩니다 - 예를 들어, 내성을 사용하여 가변성을 결정할 때).

인트로 검사는 위임이나 데이터 원본과 같이 명시 적으로 선언 된 상황에서 잘 작동합니다. 일부 @optional 메소드를 구체적으로 정의하는 @protocol 선언이있는 곳.