performSelector
NSObject.h
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
performSelector的使用
1.無(wú)參數(shù)調(diào)用
[self sendMessage];
- (void)sendMessageWithNumber:(NSString *)number {
NSLog(@"%@",number);
}
2.單個(gè)參數(shù)調(diào)用
[self sendMessageWithNumber:@"Number"];
- (void)sendMessageWithNumber:(NSString *)number {
NSLog(@"%@",number);
}
3.兩個(gè)參數(shù)調(diào)用
[self sendMessageWithNumber:@"Number" count:@"count"];
- (id)sendMessageWithNumber:(NSString *)number
count:(NSString *)count {
NSLog(@"%@ %@",number,count);
return nil;
}
performSelector 不能傳遞三個(gè)以及三個(gè)以上的參數(shù)。假如需要傳的話(huà),可以使用 NSInvocation 或者是 objc_msgSend
performSelectorOnMainThread
NSThread.h
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
基于默認(rèn)模式調(diào)用主線(xiàn)程中接收器的方法,該方法不應(yīng)該有明確的返回值并且最多只有一個(gè)id類(lèi)型的參數(shù),或者沒(méi)有參數(shù)。wait指定是否阻塞當(dāng)前線(xiàn)程直到指定選擇器在主線(xiàn)程中執(zhí)行完畢。選擇YES會(huì)阻塞這個(gè)線(xiàn)程;選擇NO,本方法會(huì)立刻返回。如果當(dāng)前線(xiàn)程也是主線(xiàn)程,選擇YES,消息會(huì)立即派發(fā),處理。
``
例如
NSLog(@"1");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"2");
sleep(2);
NSLog(@"3");
});
[self performSelectorOnMainThread:@selector(sendMessageWithNumber:) withObject:@"4" waitUntilDone:YES];
- (void)sendMessageWithNumber:(NSString *)number {
NSLog(@"%@",number);
}
輸出結(jié)果
1 4 2 3
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thrwithObject:(nullable id)arg waitUntilDone:(BOOL)wait;
調(diào)用指定線(xiàn)程中的某個(gè)方法。
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thrwithObject:(nullable id)arg waitUntilDone:(BOOL)wait;
開(kāi)啟子線(xiàn)程在后臺(tái)運(yùn)行
performSelector afterDelay
NSRunLoop.h
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
這兩個(gè)方法為異步執(zhí)行,即使delay傳參為0,仍為異步執(zhí)行。只能在主線(xiàn)程中執(zhí)行,在子線(xiàn)程中不會(huì)調(diào)到aSelector方法。可用于當(dāng)點(diǎn)擊UI中一個(gè)按鈕會(huì)觸發(fā)一個(gè)消耗系統(tǒng)性能的事件,在事件執(zhí)行期間按鈕會(huì)一直處于高亮狀態(tài),此時(shí)可以調(diào)用該方法去異步的處理該事件,就能避免上面的問(wèn)題。
在方法未到執(zhí)行時(shí)間之前,取消方法為:
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;
注意:調(diào)用該方法之前或在該方法所在的viewController生命周期結(jié)束的時(shí)候去調(diào)用取消函數(shù),以確保不會(huì)引起內(nèi)存泄露。
例如
NSLog(@"1");
[self performSelector:@selector(sendMessageWithNumber:) withObject:@"2" afterDelay:3];
NSLog(@"3");
打印出 1 3 2
而如下則打印出 1 3
dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
NSLog(@"1");
[self performSelector:@selector(sendMessageWithNumber:) withObject:@"2" afterDelay:3];
NSLog(@"3");
});
NSLog(@"1");
[self performSelector:@selector(sendMessageWithNumber:) withObject:@"2" afterDelay:3];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(sendMessageWithNumber:) object:@"2"];
NSLog(@"3");
打印結(jié)果 1 3,因?yàn)榇蛴?code>2的事件已經(jīng)在執(zhí)行前被取消了
NSInvocation
SEL selector = @selector(sendMessageWithNumber:count:);
// 方法簽名
NSMethodSignature *singnature = [self methodSignatureForSelector:selector];
if (singnature) {
// NSInvocation : 利用一個(gè)NSInvocation對(duì)象包裝一次方法調(diào)用(方法調(diào)用者、方法名、方法參數(shù)、方法返回值)
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:singnature];
[invocation setTarget:self];
[invocation setSelector:@selector(sendMessageWithNumber:count:)];
NSString *number = @"1111";
NSString *number2 = @"2ss";
// 設(shè)置參數(shù)
[invocation setArgument:&number atIndex:2];
[invocation setArgument:&number2 atIndex:3];
// 調(diào)用方法
[invocation invoke];
// 獲取返回值
NSString *result;
if (singnature.methodReturnLength != 0) {// 有返回值類(lèi)型,才去獲得返回值
[invocation getReturnValue:&result];
}
NSLog(@"%@",result);
} else {
//可以?huà)伋霎惓R部梢圆徊僮鳌? NSLog(@"singnature is nil");
}
調(diào)用時(shí)可以傳入多個(gè)參數(shù);
但是要注意判斷是否是簽名成功;
因?yàn)榍皟蓚€(gè)參數(shù)分別是方法調(diào)用者、方法名,因?yàn)樽约簜魅氲膮?shù)是從第三個(gè)開(kāi)始;
objc_msgSend
objc_msgSend
SEL selector = @selector(sendMessageWithNumber:count:);
NSString *result = ((NSString * (*) (id, SEL, NSString *, NSString *))objc_msgSend)(self, selector,@"2",@"3");
NSLog(@"%@",result);
打印結(jié)果如下
2 3
3333