ios - respondsToSelector: 和 conformsToProtocol:的区别
PHPz
PHPz 2017-04-17 17:46:29
0
1
554

首先,我的理解是:
(1)conformsToProtocol:@protocol( )是用来检查对象是否实现了指定协议类的方法;
(2)respondsToSelector:@selector( )用于判断某个类/实例(包括基类)中是否包含某个方法,仅仅判断方法名是否有和@selector(...)中的方法名一致的,而不关注该方法是否有实现,是这样吗???

我主要是对(2)有疑惑,产生疑惑的原因是:
// 首先定义一个分类
// @interface NSArray (MutableDeepCopy)
// - (NSMutableArray *)mutableDeepCopyOfArray;
// @end

@implementation NSArray (MutableDeepCopy)

// - (NSMutableArray *)mutableDeepCopyOfArray {


NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:[self count]];
for (int i = 0; i < [self count]; i++) {
    id oneValue = [self objectAtIndex:i];
    id oneCopy = nil;
    if ([oneValue respondsToSelector:@selector(mutableDeepCopyOfArray)]) {
        oneCopy = [oneValue mutableDeepCopyOfArray];
    }
    else if ([oneValue respondsToSelector:@selector(mutableCopy)]) {
        oneCopy = [oneValue mutableCopy];
    }

    if (oneCopy == nil) {
        oneCopy = [oneValue copy];
    }
    [newArray addObject:oneCopy];
}
return newArray;

}
@end

// - (void)touchesBegan:(NSSet<UITouch > )touches withEvent:(UIEvent *)event
{

NSMutableArray *arr = [[NSMutableArray alloc]  initWithCapacity:12];
NSNumber *Num = [NSNumber  numberWithInteger:12345];
[arr  addObject:Num];
NSMutableArray *arr2 = [arr  mutableDeepCopyOfArray];

}

// 当数组中包含了NSNumber这种类型时,使用该分类方法执行深拷贝时,会报错;
错误很常见,很好理解,如下:
-[__NSCFNumber mutableCopyWithZone:]: unrecognized selector sent to instance 0xb000000000004d23

当我把 else if ([oneValue respondsToSelector:@selector(mutableCopy)]) 换成
else if ([oneValue conformsToProtocol:@protocol(NSMutableCopying)])时,程序正常执行,不报错;

所以,我觉得, respondsToSelector:@selector(mutableCopy),仅仅是从调用对象(或其父类)中,寻找是否有方法名为mutableCopy的方法,只要找到该方法就返回YES,并不强调一定要有mutableCopy方法的实现;而且恰好NSObject中有mutableCopy方法的声明,所以恰好能返回YES,但程序在执行后,崩溃了,因为mutableCopy方法没有实现,即mutableCopyWithZone:方法没有实现;

PHPz
PHPz

学习是最好的投资!

모든 응답(1)
大家讲道理

conformsToProtocol은 클래스가 특정 프로토콜을 준수하는지 여부를 확인하는 것입니다. 클래스가 프로토콜의 메소드를 구현하는지 여부와는 아무런 관련이 없습니다(물론 프로토콜에서 필수로 선언된 메소드를 구현해야 합니다).

respondsToSelector는 클래스나 상위 클래스가 특정 메시지에 응답할 수 있는지 여부를 감지하는 것입니다. 귀하의 예에서 NSObject는 mutableCopy 메시지에 응답할 수 있고 NSNumber는 NSObject의 하위 클래스이므로 responseToSelector가 true를 반환하는 데 문제가 없습니다. responseToSelector는 단순히 메소드 이름만 확인하는 것이 아니라, 메소드 선언은 있지만 구현은 없어도 상관없습니다. 반드시 구현해야 하는 요구 사항입니다. NSObject 클래스에는 설명서에 명시된 대로 mutableCopy 메서드가 구현되어 있습니다.
mutableCopyWithZone에서 반환된 개체를 반환합니다.
이는 NSMutableCopying 프로토콜을 채택하는 클래스에 대한 편의 메서드입니다. mutableCopyWithZone:.

에 대한 구현이 없습니다.

따라서 NSObject의 mutableCopy 메서드는 mutableCopyWithZone을 호출하고 결과를 반환하는 것이라고 추측할 수 있습니다. 클래스가 mutableCopyWithZone 메서드를 구현하지 않으면 예외가 발생합니다.

위 프로그램이 충돌한 이유는 mutableCopy 메서드가 구현되지 않았기 때문도 아니고,responsToSelector에서 반환된 결과가 실제로 예상했던 결과였기 때문도 아닙니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿