『iOS概念性解說』SEL詳解

其實這篇文章是對上一篇文章的補充(『iOS 概念性解說』一篇文章搞懂 Block 和 Delegate),因為SEL也是對于代碼的傳入,不同的是,Block 和 Delegate是代碼的傳入,SEL是方法的傳入,Block 和 Delegate可以做回調(diào),而SEL是用來做觸發(fā)的,為什么后面會講到。


SEL

聲明

SEL s1 = @selector(test);
SEL s2 = NSSelectorFromString(@"test");

名字

NSString *str = NSStringFromSelector(@selector(test));

執(zhí)行

[self performSelector:s1 ];
[self performSelector:@selector(test) ];
//帶有參數(shù)的
 [test performSelector:@selector(test2:) withObject:@"param"];

判斷

[self respondsToSelector:s1]

整體

上面介紹了基本語法,在這里需要整體來看一下。
我們可以建立一個Test類
Test.h

@interface Test : NSObject
//無參數(shù)的方法
- (void)test1;
//有參數(shù)的方法
- (void)test2:(NSString *)str;
// 觸發(fā)
- (void)perform:(SEL)aSelector with:(NSObject*) object;
@end

Test.m

#import "Test.h"

@implementation Test
- (void)test1
{
    NSLog(@"無參數(shù)");
}

- (void)test2:(NSString *)str
{
    NSLog(@"有參數(shù)%@",str);
}
- (void)perform:(SEL)aSelector with:(NSObject*) object{
    if ([object respondsToSelector:aSelector]) {
        [object performSelector:aSelector];
    }
}
@end

有了這個類,我們可以調(diào)用一下試試看了:

#import "ViewController.h"
#import "Test.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    SEL s1 = @selector(test);
    SEL s2 = NSSelectorFromString(@"test");
   NSString *str = NSStringFromSelector(@selector(test));
    NSLog(@"%@",str);
    Test *test = [Test new];
    [test performSelector:@selector(test1)];
    [test performSelector:@selector(test2:) withObject:@"param"];
    [self performSelector:s1 ];
    [self performSelector:s2 ];
    [self performSelector:@selector(test) ];
    if ([self respondsToSelector:s1]) {
        NSLog(@"含有test方法");
    }
    if ([self respondsToSelector:@selector(test1)]) {
        NSLog(@"含有test1方法");
    }else{
        NSLog(@"不含有test1方法");
    }
    [test perform:@selector(testEnter) with:self];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (void)test{
    NSLog(@"test");
}
- (void)testEnter{
    NSLog(@"test inter");
}
@end

運行上述代碼,可以看出,對一個類使用performSelector可以執(zhí)行該類中的SEL,要注意該類需要是NSObject的子類,因為performSelector是NSObject中的方法。
在執(zhí)行SEL前,我們需要確認該類中是否含有這個方法,可以使用respondsToSelector進行判斷,這樣更加安全一下,然后再執(zhí)行。
上述代碼中testEnter這個方法是傳入Test類中執(zhí)行的,我們通過[test perform:@selector(testEnter) with:self];傳入到Test類中,我們執(zhí)行了:

- (void)perform:(SEL)aSelector with:(NSObject*) object{
    if ([object respondsToSelector:aSelector]) {
        [object performSelector:aSelector];
    }
}

UIButtion的點擊事件就是這樣實現(xiàn)的。
可能有人會問,為什么SEL不能做為回調(diào),這是由于SEL的執(zhí)行是需要他的類調(diào)用performSelector,也就是我們需要將類傳遞進來,如果有參數(shù),還需要傳遞上下文參數(shù),這樣做會增大程序的耦合性,一般不這么做。
那為什么觸發(fā)可以?以UIButtion為例,我們把方法傳入UIButtion,同時UIButtion本身也需要當前的ViewController。這是我們都傳遞進去是沒有問題的,即便點擊事件的方法需要傳入自己作為參數(shù)也是可以的,因為這段代碼本身就是在button中執(zhí)行的,不用withObject,直接self即可。

總結(jié)

結(jié)合之前的文章,綜上所述,根據(jù)不同情況,使用合理的方式傳入代碼,能夠提高程序的可讀性和可維護度。
有疑問的朋友歡迎給我留言指正,或者關(guān)注我的公眾號留言:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,624評論 30 472
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,067評論 0 9
  • 西安的天氣總是陰晴不定,像小孩子的脾氣,叫人難以琢磨。剛才還是艷陽高照,城墻下,吃過晚飯的市民都聚集于此,嬉鬧玩樂...
    談談談是誰閱讀 198評論 0 1
  • 一個想要復辟的領(lǐng)導也好,老農(nóng)民也罷,都是有血有肉的mankind。文字不在于辭藻華麗,這種小生活細情感更加感人肺腑...
    wynn木木閱讀 206評論 0 0
  • 恐怕未必,溫水煮青蛙的實驗不一定真實,但溫水煮青蛙的理論卻人所熟知。在舒適的環(huán)境中,人往往會忘記危險,我不愿意象那...
    東升旭日閱讀 897評論 19 18

友情鏈接更多精彩內(nèi)容