前言:
- 本篇文章介紹的是以下三個作用相似的函數(shù)或方法的使用,以及它們具體的使用區(qū)別。
BOOL class_respondsToSelector(Class cls, SEL sel)
- (BOOL)respondsToSelector:(SEL)aSelector;// 方法聲明在NSObject協(xié)議中
+ (BOOL)instancesRespondToSelector:(SEL)aSelector;// 方法聲明在NSObject類中
三個函數(shù) \ 方法的作用都是判斷是否響應了某個方法,或者說是判斷某個方法有沒有被實現(xiàn)。它們都需要用類或類的實例當作參數(shù)或調(diào)用,那先創(chuàng)建一個類 Person 并在類中添加幾個方法,方法示例如下:
// Person.h
@interface Person : NSObject
// 未聲明
@end
// Person.m
@implementation Person
+ (void)run
{
NSLog(@"run");
}
- (int)ages
{
return 30;
}
@end
我們現(xiàn)在通過一組代碼看看它們的區(qū)別,各個 BOOL 值的打印結果標注在每一行的后面
Person *p = [[Person alloc] init];
BOOL yn1 = class_respondsToSelector([Person class], @selector(ages)); // YES
BOOL yn2 = class_respondsToSelector([Person class], @selector(run)); // NO
BOOL yn3 = [[Person class] respondsToSelector:@selector(ages)]; // NO
BOOL yn4 = [[Person class] respondsToSelector:@selector(run)]; // YES
BOOL yn5 = [p respondsToSelector:@selector(ages)]; // YES
BOOL yn6 = [p respondsToSelector:@selector(run)]; // NO
BOOL yn7 = [[Person class] instancesRespondToSelector:@selector(ages)]; // YES
BOOL yn8 = [[Person class] instancesRespondToSelector:@selector(run)]; // NO
1 . class_respondsToSelector 函數(shù)雖然參數(shù)需要傳入一個類,但由yn1 和 yn2 的結果可知該函數(shù)是判斷傳入類中是否實現(xiàn)了指定的『實例方法』。
2 . respondsToSelector 方法聲明在 NSObject 協(xié)議中,調(diào)用者可以是實例也可以是類:由yn3 和 yn4 的結果可知,當調(diào)用者是類時,該方法是判斷這個類中是否實現(xiàn)了指定的『類方法』;由yn5 和 yn6 的結果可知,當調(diào)用者是類的實例時,該方法是判斷這個類中是否實現(xiàn)了指定的『實例方法』。
3 . instancesRespondToSelector 方法聲明在 NSObject 類中且是類方法,只能被類調(diào)用,由yn7 和 yn8 的結果可知,該方法是判斷類中是否實現(xiàn)了指定的『實例方法』。
可知:
class_respondsToSelector 函數(shù)和 instancesRespondToSelector 方法作用相同,和 respondsToSelector 方法被實例調(diào)用時的作用也相同。
注:上述所有結論也適用于子類,比如定義一個子類 LittlePerson 繼承類 Person ,即使 LittlePerson 中沒有重寫 Person 的類方法和實例方法,也盡管 Person 的類方法和實例方法沒有在 Person.h 文件中聲明,但是子類仍然能響應父類的私有方法。