【问题标题】:How to make sure your delegate(iphone, cocoa) is thread safe?如何确保您的委托(iphone、cocoa)是线程安全的?
【发布时间】:2010-10-29 02:14:18
【问题描述】:

我已经看到了一些使用多线程委托与 cocoa 的 URL 加载系统进行异步图像加载的示例。

我认为过程如下。

线程 1: 给线程 2 一个要执行的操作,以及一个线程 2 将在完成后访问的委托。

线程 2: 完成操作后,调用线程 1 传递的委托上的预定义选择器。

我想用我自己的类实现类似的功能(使用委托进行异步处理)。 下面的伪代码类似于上面概述的过程,但为了讨论线程安全,我想把它更详细。

线程 1:
[开始临界区]
设置委托,以便线程 2 可以访问
[结束临界区]
触发操作

-(void) dealloc(委托对象的类) {
[开始临界区]
将委托设置为 null
[结束临界区]
}

线程 2:
实际运作中
- 完成后.. [开始关键部分]
获得委托
[委托 performSelectorOnMainThread @someSelector];
[结束关键部分]

现在,我担心访问委托的线程安全。 换句话说,当委托对象可以随时离开而无需等待操作完成时,第二个线程如何确保委托仍然有效

上面的伪代码是我做过的最好的尝试,想知道它是否真的可以工作。 此外,我从未见过任何尝试在类似的工作中使委托线程安全,例如http://www.markj.net/iphone-asynchronous-table-image/ 临界区安全防护不是必须的吗?

谢谢

【问题讨论】:

    标签: iphone multithreading delegates


    【解决方案1】:

    您可以简单地让工作人员保留其回调目标。然后,保证它在进行回调时就在附近。这就是NSTimer 所做的。

    【讨论】:

    • 啊,我想投票,但我缺乏声誉。(堆栈溢出的新手)
    • 顺便说一句,我认为您通常希望(分配)代表以防止循环保留。
    • 从某种意义上说,这并不是真正的代表,因为您正在咨询政策或对无论如何将要处理的事件进行破解。 “委托”只是回调函数的一部分 - 将其称为“目标”:由于 Obj-C 是面向对象的,因此您需要函数(方法)和调用方法的东西。这是工作对象存在的全部意义:计算一些东西,然后回调。启动它的对象应该会收到回调。
    • 我认为这也是NSTimer 保留其目标背后的想法。但是NSTimer 最终确实会导致保留周期问题,因为它通常不是一次性的,“去,做这个,然后回到我身边”,而是一个反复发生的事件,它永远保持对其目标的拥有引用。 (或者至少在它失效之前。)
    • 嗯,有时启动它的对象可能不太关心接收回调,就像在图像加载中一样。例如,用户正在浏览 iphone 应用商店的游戏类别(并且正在加载表格视图的图像)并决定切换到不同的类别。在这种情况下,“游戏类别代表”可能对接收不必要的图像不感兴趣。
    【解决方案2】:

    NSURLConnection 在辅助线程上加载数据,但只在主线程上调用委托方法,因此从使用 NSURLConnection 数据的角度来看,您不必担心线程安全。它在 NSURLConnection 中得到处理。

    就保持有效的委托而言,您可能只想保留对 URL 连接的引用,并在释放控制对象时取消任何挂起或正在进行的连接。

    -(void)取消 NSURLConnection 状态:

    “一旦调用此方法,接收者的委托将不再收到此 NSURLConnection 的任何消息。”

    【讨论】:

    • 啊,谢谢,我猜“取消”的作用类似于我对 [关键部分] 所做的事情。好吧,我问我如何用我自己的类实现 NSURLConnection 的功能,但很高兴知道其他类如何处理它。假设用户没有取消操作,当代理在完成下载后离开时,NSURLConnection 是如何处理的?
    • 连接失败或成功完成后,它永远不会向其代理发送另一条消息。文档:“除非 NSURLConnection 收到取消消息,否则委托将收到一个且只有一个 connectionDidFinishLoading: 或 connection:didFailWithError: 消息,但绝不会同时收到两者。此外,一旦发送任何消息,委托将不会收到给定 NSURLConnection 的更多消息。”
    猜你喜欢
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2016-04-20
    • 1970-01-01
    相关资源
    最近更新 更多