performSelector:onThread:withObject:waitUntilDone理解
直接看代碼
//
// ViewController.m
// RunLoopDemo
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, assign) BOOL isAborted;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self threadInfo:@"UI"];
_isAborted = NO;
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread:) object:nil];
[thread start];
// When performing a selector on another thread, the target must have an active run loop
[self performSelector:@selector(test:) onThread:thread withObject:nil waitUntilDone:NO];
}
- (void)newThread:(id)obj {
@autoreleasepool {
NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
while (!_isAborted) {
[currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
NSLog(@"線程停止");
}
}
- (void)test:(id)obj {
[self threadInfo:@"test"];
_isAborted = YES;
}
- (void)threadInfo:(NSString *)info {
NSLog(@"%@--%@", info, [NSThread currentThread]);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
有的人無(wú)法理解為什么要通過(guò)[self performSelector:@selector(test:) onThread:thread withObject:nil waitUntilDone:NO];
中的test:
方法來(lái)更新_isAborted
狀態(tài)生宛。為什么不在[thread start]
之后直接調(diào)用弊攘。原因其實(shí)是這里通過(guò)selector方法將其設(shè)置成yes的原因是雖然設(shè)置為yes鱼的,但是這時(shí)候runloop所在的線程其實(shí)是并不知道_isNewThreadAborted被重新賦值了琐脏。runloop沒有被任務(wù)事件喚醒栅组。所以正確的方法是通過(guò)使用selector來(lái)喚醒Runloop。 并且要注意兑徘,在執(zhí)行performSelector:onThread:withObject:waitUntilDone
方法時(shí)候价匠,如果是在另外一個(gè)線程執(zhí)行,必須保證另外的線程是有一個(gè)runloop.具體的使用可以參考AFNetworking.