gpt4 book ai didi

ios - 调用 (NSRunLoop)-run() 和 CFRunLoopRun() 有什么区别

转载 作者:行者123 更新时间:2023-11-29 13:56:14 26 4
gpt4 key购买 nike

我正在学习 iOS runloop。网上的一些文章向我展示了这样的代码:

- (void)memoryIssue {
for (int i = 0; i < 10000; i++) {
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runThread) object:nil];
[thread setName:thread_name];
[thread start];
[self performSelector:@selector(stopThread) onThread:thread withObject:nil waitUntilDone:YES];
}
}

- (void)runThread {
NSLog(@"current thread = %@", [NSThread currentThread]);
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
static NSMachPort *port;
if (!port) {
port = [NSMachPort port];
}
[runLoop addPort:port forMode:NSDefaultRunLoopMode];
// CFRunLoopRun(); //All right
[runLoop run]; // ⚠️Thread not exit...!
}

- (void)stopThread {
CFRunLoopStop(CFRunLoopGetCurrent());
NSThread *thread = [NSThread currentThread];
[thread cancel];
}

当使用 CFRunLoopRun() 时,一切正常。在每个 for 循环中,都会创建一个线程,然后退出。然而对于[runLoop run],内存不断增长,最终应用程序由于“-[NSThread start]: Thread creation failed with error 35”(达到线程数上限?)而终止。

**我的问题:

  1. -run()CFRunLoopRun() 有什么区别?我认为前者只是后者的包装。

  2. 这段代码似乎是想展示退出线程的正确方法。在实际开发中是否实用?**

最佳答案

CFRunLoopRun 文档告诉我们:

The current thread’s run loop runs in the default mode (see Default Run Loop Mode) until the run loop is stopped with CFRunLoopStop or all the sources and timers are removed from the default run loop mode.

但是运行 documentation没有提及这一点。它说:

If no input sources or timers are attached to the run loop, this method exits immediately; otherwise, 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.

但它继续警告:

Manually removing all known input sources and timers from the run loop is not a guarantee that the run loop will exit. macOS can install and remove additional input sources as needed to process requests targeted at the receiver’s thread. Those sources could therefore prevent the run loop from exiting.

If you want the run loop to terminate, you shouldn't use this method. Instead, use one of the other run methods and also check other arbitrary conditions of your own, in a loop. A simple example would be:

BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

where shouldKeepRunning is set to NO somewhere else in the program.

我还建议您引用 Threading Programming Guide: Terminating a Thread .

你问:

The code seems to intend to show the right way to exit a thread. Is it practical in real-life developing?

不,编写我们自己的 NSThread 代码已经非常少见了。 Grand Central Dispatch (GCD) 消除了所有这些麻烦。它更高效(因为它有准备就绪的工作线程池,不需要旋转循环或每个线程的 NSRunLoop 等)并且更容易编写代码。我不建议编写 NSThread 代码,除非存在一些您无法使用 GCD 轻松解决的非常具体的问题。


顺便说一下,注意当你写NSThread代码的时候,你真的应该有你的线程set up its own autorelease pool (虽然我们会使用 @autoreleasepool { ... } 而不是该指南中概述的模式)。例如:

- (void)runThread {
@autoreleasepool {
...
}
}

如果您使用 GCD,此内存管理会为您处理。


如果您想了解有关 NSThreadNSRunLoop 等的更多信息,请参阅 Threading Programming Guide .或者使用 GCD 为自己省去很多痛苦.

关于ios - 调用 (NSRunLoop)-run() 和 CFRunLoopRun() 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55811820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com