【问题标题】:is it ok to use of a notification to communication back to the main thread of an IOS app? (cf performSelectorOnMainThread)可以使用通知与 IOS 应用程序的主线程进行通信吗? (参见 performSelectorOnMainThread)
【发布时间】:2011-11-07 04:13:24
【问题描述】:

是否可以使用通知与 IOS 应用程序的主线程进行通信? (参见 performSelectorOnMainThread)。也就是说,有没有为此目的的问题?

背景

  • 想要从后台线程回调主 UI 线程(例如 performSelectorInBackground)
  • 可以使用 performSelectorOnMainThread 进行通信,但想知道是否可以使用通知?

例如

 [[NSNotificationCenter defaultCenter] postNotificationName:@"ModelChanged" object:self];

【问题讨论】:

    标签: iphone ios nsthread nsnotifications nsnotificationcenter


    【解决方案1】:

    其实有一个问题;你会随机崩溃!这就是我的经验。这与接收通知的对象在与通知的发送者相同的线程上这样做有关。

    来自Apple iOS Documentation on Notification Centers

    在多线程应用程序中,通知总是以 发布通知的线程,可能不是 观察者注册自己的同一线程。

    这难免会让你头疼。

    如果主线程上的某些东西正在接收通知,我发现从后台线程弹出到主线程来发出通知是最安全的方法。这很简单:

    //Call this to post a notification and are on a background thread      
    - (void) postmyNotification{
      [self performSelectorOnMainThread:@selector(helperMethod:) withObject:Nil waitUntilDone:NO];
    }
    
    //Do not call this directly if you are running on a background thread.
    - (void) helperMethod{
      [[NSNotificationCenter defaultCenter] postNotificationName:@"SOMENAME" object:self];
    }
    

    不幸的是,这在发送者和接收者之间引入了微妙的耦合,因为您正在修改发送者以适应接收者。

    正如 XJones 指出的那样,一个更好的解决方案是让发送者在它决定的任何线程上发送通知,然后让侦听器负责使用适当的线程来执行它需要的任何操作。

    希望对您有所帮助。

    【讨论】:

    • 我在回答的评论中引用了这个问题。我不喜欢发布通知的对象与观察者之间的耦合的完全 b/c 解决方案。对象张贴应该张贴在它喜欢的任何线程上。接收者应该在它需要的线程上处理通知(例如,接收者可以将通知转发到主线程或任何其他线程)。 Apple 在其示例代码中也使用了这种方法。
    • 我完全同意。我已经更新了我的答案以反映这种方法。
    • @PixelCloudSt 我理解这种方法的耦合,但我该如何让接收器在多个线程上监听?
    • @AlexGodbehere 侦听器无法指示它在哪个线程上接收消息。你最好的策略是在它进入的任何线程上接收消息(因为除非你想控制发送者,否则你别无选择),然后从接收者那里,在你希望的任何线程上执行你想要的任何操作使用。希望能回答您的问题。
    • [[NSOperationQueue mainQueue] addOperationWithBlock:^ {}]; 通常是performSelectorOnMainThread: 的更干净的改动
    【解决方案2】:

    是的,通知可用于此目的。您可以使用任何您喜欢的方法(协议、通知、直接消息传递)跨线程在对象之间进行通信。你选择哪一个取决于你觉得最合适的。当发布通知的对象对观察通知的对象一无所知时,通知就很棒。如果您发送消息(例如performSelectorOnMainThread),则发送消息的对象确实需要知道将消息发送到的对象(通常通过协议)。

    【讨论】:

    • 好的,谢谢 - 我遇到了一些问题 (stackoverflow.com/questions/8032987/…),想知道这是否是原因
    • 好的,刚刚发布了一个答案。我通常发现在处理程序中强制执行任何线程要求比在发送方更好。例如,您可以确保始终在主线程上发布通知,但这很乏味。发布对象不应该关心。收件人确实很在意,如果合适,应该将消息转发到主线程。
    猜你喜欢
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多