我的iOS委托方法是否应该始终在主线程上返回?

我的iOS委托方法是否应该始终在主线程上返回?,ios,delegates,queue,grand-central-dispatch,Ios,Delegates,Queue,Grand Central Dispatch,这是一个“最佳实践”问题,我似乎无法在网上找到一个好答案。我正在创建一个静态代码库,其中提供了几个用于进度反馈的委托方法 库管理它自己的队列,因此下载之类的事情显然不会在主线程上完成,但我的问题是,我应该确保我的委托方法总是在主线程上调用,还是可以从我正在使用的队列线程中调用它们?如果开发人员想在我的委托方法中进行UI更新,那么可以依靠使用库的开发人员检查他是否在主线程上 干杯, Sam显然,您必须在主线程中调用委托方法,因为如果我没有错的话,您的委托方法将被传递给某个委托对象(用户的类) 假设

这是一个“最佳实践”问题,我似乎无法在网上找到一个好答案。我正在创建一个静态代码库,其中提供了几个用于进度反馈的委托方法

库管理它自己的队列,因此下载之类的事情显然不会在主线程上完成,但我的问题是,我应该确保我的委托方法总是在主线程上调用,还是可以从我正在使用的队列线程中调用它们?如果开发人员想在我的委托方法中进行UI更新,那么可以依靠使用库的开发人员检查他是否在主线程上

干杯,
Sam

显然,您必须在主线程中调用委托方法,因为如果我没有错的话,您的委托方法将被传递给某个委托对象(用户的类)


假设您正在队列中下载数据,当数据下载时,您将通过将其传递给用户类的某个对象来调用委托方法,因此它必须位于主线程中。

您可以采用任何一种方式;你只需要好好记录一下

一些API会在主线程上调用您,一些API会在用于启动工作的线程(或runloop)上调用您,而其他API则根本不做任何保证。有些甚至会让您传入用于所有回调的GCD队列

请记住,委托/回调可能会阻塞相当长的时间,因此,如果您的API需要尽快恢复工作,您当然希望将其分派到另一个线程或队列


话虽如此,除非性能对您或API用户至关重要,否则我会选择对开发人员来说最方便的主线程。

当我制作自己的下载管理器时,我一直在委托方法调用运行连接对象实例的次线程,但这是因为我有一个“控制员“这是在主线程上调度成功块。在我看来,这取决于库所涉及的级别,如果您认为委托在大多数情况下会调用包含UIKit对象的子例程的方法,因为它们不是线程安全的,那么我将选择在主线程上分派它们。如果您认为在委托之后,您的库的用户可以对数据进行进一步的细化,我将选择停留在另一个线程上,但在文档中明确说明这一点。还有一点:速度,取决于三个优先级,辅助线程可能会非常慢。
[编辑]

在下载管理器中,KVO或通知是处理连接的更好方式,正如苹果工程师奎因在WWDC视频中所述。

当你说“显然”。。。为什么显而易见?委托方法仍然正确地传递回委托对象,即使它们不在主线程上,这仅仅意味着用户的类需要确保它在主线程上运行,如果它想更新UI?(仅供参考,不是我否决了你的答案!)我的意思是,如果你把它留给用户,那么用户就可以通过你的库代码来知道他是否应该调用主线程或其他线程。虽然我不是天才,但不管我的经验如何,你应该让用户轻松使用这个库。(我对你的问题投了赞成票,我也在等待其他人的回答,你提出的观点很好).好的,谢谢…听起来这真的取决于我提供的文档级别,而且最佳实践被认为是为了让实现它的开发人员更容易,而不是为了遵循任何既定的规则。谢谢你的回答,在这种情况下,“最佳实践”似乎真的取决于场景。这真的取决于。但我建议始终使用“内部专用”队列来执行客户端的块。这是避免用户代码在调用dispatch_sync()时意外死锁的唯一可靠方法在街区的某个地方。谢谢,是的,我正在使用库中的内部私有队列。谢谢你的评论…首先,Quinn是一个传奇!其次,我的问题是,我的库远不止充当下载管理器,事实上下载管理器是库中的一个组件。所以我想避免使用KVO/通知一方面,另一方面,授权方法……但除此之外,是的,我同意你的看法。是的,“爱斯基摩人”是一个超级英雄,他真的是一个好人,总是解释事情。