gpt4 book ai didi

objective-c - 在单独的线程上调用我的方法有哪些不同的方式?

转载 作者:IT王子 更新时间:2023-10-29 07:47:43 26 4
gpt4 key购买 nike

我有一些数据计算方法(让它成为“myMethod:”),我想将调用转移到另一个线程,因为我不想阻止我的主要 UI 功能。所以,开始研究如何在另一个线程上调用我的方法。据我所知,目前有很多不同的方法可以做到这一点。这是一个列表:

a) 使用纯线程(自 iOS 2.0 起可用):

[NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self withObject:_myParamsArray];

b) 使用简单的快捷方式(自 iOS 2.0 起可用)。可从继承的 NSObject 获得,但该方法也属于 NSThread 类:

[self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray];

c) 使用 Grand Central Dispatch 队列的新方法(自 iOS 4.0 起可用):

dispatch_async(dispatch_get_global_queue(0, 0),
^ {
[self myMethod:_myParamsArray];
});

d) 以某种方式,使用一些类,如 NSOperation、NSBlockOperation 或 NSOperationQueue,尽管不确定具体如何去做(一些例子将不胜感激)

目前,我使用了案例“b”,但对优缺点和其他相关建议感到好奇。

更新:e) 还找到了另一种执行类似线程处理的方法 - Run loops .这是苹果文档的摘录:

A run loop is an event processing loop that you use to schedule work and coordinate the receipt of incoming events. The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.

恕我直言,您或多或少正在处理相同的任务 - 如何在单独的线程上调用您的方法以进行异步操作。

更新 2:已经对 NSInvocationOperation 和 NSOperationQueue 有了一些经验,恕我直言,这很方便。根据 Apple 文档,GCD 和 NSOperations 是实现多线程的首选方式。而且,从 iOS 4.0 开始,NSOperations 在 GCD 上运行。简而言之,您实例化 NSIvocationOperation(作为对您的方法的调用),然后实例化 NSOperationQueue 并将调用添加到队列中。 NSOperationQueue 是足够聪明的东西,你可以实例化多个 NSIvocationOperation 对象(包装你的方法调用)并将它们添加到 NSOperationQueue。剩下的就放心了。 NSOperationQueue 确定它需要多少并行线程来执行调用(NSInvocationOperation)并为您处理。它可能会在线程 A 上执行第一个调用,然后在线程 B 上执行第二个调用,在线程 C 上执行第三个调用,然后在线程 B 上执行第四个调用,因此您不必担心这一点。但是如果你愿意,你可以告诉最大线程 NSOperationQueue 如何用于执行调用(例如 1),但我不需要那个。默认情况下,所有任务都在主线程以外的线程上执行,因此操作队列默认是异步的。此外,如果你想在一个严格的队列中执行你的方法调用(每个包装在单独的 NSInvocationOperation 中),那么你可以添加依赖项,这样 NSOperationQueue 将保留方法调用顺序。这是一个例子:

// wrap your method call into NSInvocationOperation object
NSInvocationOperation *currentOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(yourMethodCall) object:nil];

// _sharedOperationQueue is a shared NSOperationQueue
// get all executing operations from the queue and get the last operation
_lastOperation = [[_sharedOperationQueue operations] lastObject];

// check if _lastOperation is not nil
if (_lastOperation) {

// if not then add dependency, so the calls would be performed in a queue
[currentOperation addDependency:_lastOperation];
}

// say - execute my method (operation)
[_sharedOperationQueue addOperation:currentOperation];

_lastOperation = currentOperation; // mark as last operation for adding dependency to the next operation

// the queue will retain invocation operation so you will release
[currentOperation release];

..... you can create another NSInvocationOperation and add it to the queue....

至于 RUNLOOP,有时您仍然会遇到它们,例如在启动/安排计时器或建立 NSURL 连接时。恕我直言,runloop 可以比作在一个线程上执行的任务队列。恕我直言,runloop 是指向作为队列运行的线程的指针:它具有可能抛出事件的任务,它们将被放置在该线程中队列的末尾。默认情况下,您应用程序中的所有任务都在单个运行循环中运行 - 在单个线程中。我说它是一个指针,因为当您的应用程序生成事件时,应用程序必须知道将该事件(触摸事件或其他委托(delegate)回调)放在哪里执行。当然,您应该阅读 runloops 以获得更详细的信息,因为这些只是我的想法。

最佳答案

通常,您更喜欢 GCD 方法。

在同步/锁定方面,它比纯线程(NSThread - pthread)更简单,并且从性能角度来看可能更准确。

使用纯线程时,问题是您可能会遇到性能问题,具体取决于可用内核/处理器的数量。

例如,如果您只有一个内核,那么创建多个线程可能会降低您的应用程序的速度,因为 CPU 将花费大部分时间从一个线程切换到另一个线程,保存堆栈、寄存器等。

另一方面,如果您有很多核心可用,那么创建很多不同的线程可能会很好。

这是 GCD 提供帮助的地方,因为它会为您进行管理。它将根据可用的系统资源创建适当数量的线程,以保证最佳利用率,并适本地安排您的操作。

但是,由于这个原因,使用 GCD 启动的任务可能不是实时的。

因此,如果您真的需要一个分离的任务立即运行,请使用显式线程。否则,使用 GCD。

希望这对你有帮助:)

编辑

关于 performSelectorInBackground 的注意事项:它只是创建一个新线程。所以与 NSThread 方法基本上没有区别。

编辑 2

NSOperation 相关的东西有点不同。在 Mac OS X 上,从 10.6 版开始,它们是使用 GCD 实现的。以前的版本使用线程。

在 iOS 上,它们仅使用线程实现。

引用

所有这些都在 Concurrency Programming Guide 中得到了很好的解释.它讨论了 GCD 和线程方法,以及有关使用和实现的大量细节。

如果你还没有读过,你应该看看。

关于objective-c - 在单独的线程上调用我的方法有哪些不同的方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8295017/

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