一、performSelector調用和直接調用區別
下面兩段代碼都在主線程中運行,我們在看別人代碼時會發現有時會直接調用,有時會利用performSelector調用,今天看到有人在問這個問題,我便做一下總結,
[delegate imageDownloader:self didFinishWithImage:image];
[delegate performSelector:@selector(imageDownloader:didFinishWithImage:)withObject:self withObject:image];
1、performSelector是運行時系統負責去找方法的,在編譯時候不做任何校驗;如果直接調用編譯是會自動校驗。如果imageDownloader:didFinishWithImage:image:不存在,那么直接調用 在編譯時候就能夠發現(借助Xcode可以寫完就發現),但是使用performSelector的話一定是在運行時候才能發現(此時程序崩潰);Cocoa支持在運行時向某個類添加方法,即方法編譯時不存在,但是運行時候存在,這時候必然需要使用performSelector去調用。所以有時候如果使用了performSelector,為了程序的健壯性,會使用檢查方法- (BOOL)respondsToSelector:(SEL)aSelector;
2、直接調用方法時候,一定要在頭文件中聲明該方法的使用,也要將頭文件import進來。而使用performSelector時候,可以不用import頭文件包含方法的對象,直接用performSelector調用即可。
二.person類.m文件的實現內容
- (void)invoke { //1.使用perform調用不帶參數的方法 //SEL是一個類型:方法選擇器 @selector(方法名) [self performSelector:@selector(demo1)]; //2.使用perform調用帶有一個參數的方法 [self performSelector:@selector(demo2:) withObject:@"這是一個參數"]; //3.使用perform調用帶有兩個個參數的方法 [self performSelector:@selector(demo3:withName:) withObject:@"參數1" withObject:@"參數2"]; //4.延遲調用某一個方法 //代碼不會停留在這里,這個任務會掛載后台,后面代碼繼續執行 [self performSelector:@selector(demo1) withObject:NULL afterDelay:2.5]; } //不帶參數 - (void)demo1 { NSLog(@"這是demo1"); } //帶有一個參數的方法 - (void)demo2:(NSString *)str { NSLog(@"這是demo2 str:%@",str); } //帶有兩個參數的方法 - (void)demo3:(NSString *)str withName:(NSString *)name { NSLog(@"這是demo3,str:%@ name:%@",str,name); } //私有方法 - (void)testMethod { NSLog(@"這是一個私有方法"); }
三.perform調用的演示
Person *p = [[Person alloc]init]; [p invoke]; // [p testMethod];會報錯 //使用perform調用私有方法 [p performSelector:@selector(testMethod)]; //判斷某一個對象是否響應了某一個方法 BOOL isRespond = [p respondsToSelector:@selector(testMethod)]; if (isRespond) { [p performSelector:@selector(testMethod)]; }else { NSLog(@"p沒有實現這個方法"); }