1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| - (void)viewDidLoad { [super viewDidLad]; NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; [thread start]; } - (void)run { NSLog(@"run"); } // run -> thread deallo
// 线程保活 - (void)viewDidLoad { [super viewDidLoad]; // initWithTarget:self 会强引用控制器 导致循环引用 // self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
self.stopped = false;
__weak typeof(self) weakSelf = self; self.thread = [[NSThread alloc] initWithBlock:^{ NSLog(@"run"); // [NSRunLoop currentRunLoop] 获取线程就是创建线程 // 需要往RunLoop添加Source/Timer/Observer [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
/* it runs the receiver in the NSDefaultRunLoopMode by repeatedly invoking runMode:beforeDate: In other words, this method effectively begins an infinite loop that processes data from the run loop’s input sources and timers. [[NSRunLoop currentRunLoop] run] 相当于 while (1) { [NSRunLoop currentRunLoop] runMode:<#(nonnull NSRunLoopMode)#> beforeDate:<#(nonnull NSDate *)#> } */ // NSRunLoop 的 run 方法是无法停止的,他专门用于开启一个用不销毁的线程(RunLoop) // [[NSRunLoop currentRunLoop] run];
//线程保活 while (weakSelf && !weakSelf.isStopped) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; }
NSLog(@"end"); }]; [self.thread start]; }
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 最后一个参数为 YES 会等待 线程中 test 方法执行完打印 123 // 最后一个参数为 NO 会直接打印 123 if (!self.thread) return; [self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO]; NSLog(@"123"); }
- (void)test { NSLog(@"test"); }
- (void)stop { if (!self.thread) return; // waitUntilDone 只能为 YES // NO 会造成野指针 控制销毁和子线程 stop方法同时进行 控制器坏内存 [self performSelector:@selector(stopThread) onThread:self.thread withObject:nil waitUntilDone:YES]; }
// 用于停止子线程的 RunLoop - (void)stopThread { self.stopped = true; CFRunLoopStop(CFRunLoopGetCurrent()); self.thread = nil; }
- (void)dealloc { [self stop]; // dealloc 执行完毕 weakSelf 为空 }
|