NSNotification 与dispatch_get_main_queue

2024-05-30

和---关联这个问题 https://stackoverflow.com/questions/7905192/iphone-grand-central-dispatch-main-thread我想知道关于何时使用 NSNotification(在主线程中使用观察者)与使用 GCD 将工作从后台线程分派到主线程是否有任何普遍接受的逻辑?

看来,通过通知观察者设置,您必须记住在视图卸载时拆除观察者,但随后您可以可靠地忽略通知,因为将作业分派到主线程可能会导致在视图卸载时执行块。已被卸载。

因此,在我看来,通知应该可以提高应用程序的稳定性。根据我所读到的 GCD,我假设调度选项提供了更好的性能?

UPDATE:

我知道通知和调度可以很好地协同工作,并且在某些情况下应该一起使用。我试图找出是否存在应该/不应该使用的特定情况。

一个示例:为什么我要选择主线程来从分派块激发通知,而不是仅仅在主队列上分派接收函数? (显然两种情况下接收函数都会有一些变化,但最终结果似乎是相同的)。


The NSNotificationCenter and gcd & dispatch_get_main_queue()服务于截然不同的目的。我不认为“vs”真正适用。

NSNotificationCenter提供了一种分离应用程序不同部分的方法。例如kReachabilityChangedNotificationApple的Reachability示例代码中当系统网络状态发生变化时发布到通知中心。反过来,您可以要求通知中心调用您的选择器/调用,以便您可以响应此类事件。(想想空袭警报器)

gcd另一方面,提供了一种快速分配要在您指定的队列上完成的工作的方法。它可以让您告诉系统您的代码可以在哪些点被单独剖析和处理,以利用多线程和多核 CPU。

通常(几乎总是)通知是在发布通知的线程上观察到的。除了一个 API 的显着例外......

这些概念交叉的一个 API 是NSNotificationCenter's:

addObserverForName:object:queue:usingBlock:

这本质上是一种确保在给定线程上观察到给定通知的便捷方法。虽然 ”usingBlock“参数泄露了它在幕后使用的信息gcd.

这是其用法的示例。假设我的代码中的某处有一个NSTimer每秒调用此方法:

-(void)timerTimedOut:(NSTimer *)timer{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // Ha! Gotcha this is on a background thread.
        [[NSNotificationCenter defaultCenter] postNotificationName:backgroundColorIsGettingBoringNotification object:nil];
    });
}

我想使用backgroundColorIsGettingBoringNotification作为我更改视图控制器视图背景颜色的信号。但它发布在后台线程上。好吧,我可以使用前面提到的 API 仅在主线程上进行观察。笔记viewDidLoad在下面的代码中:

@implementation NoWayWillMyBackgroundBeBoringViewController {
    id _observer;
}
-(void)observeHeyNotification:(NSNotification *)note{
    static NSArray *rainbow = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        rainbow = @[[UIColor redColor], [UIColor orangeColor], [UIColor yellowColor], [UIColor greenColor], [UIColor blueColor], [UIColor purpleColor]];
    });
    NSInteger colorIndex = [rainbow indexOfObject:self.view.backgroundColor];
    colorIndex++;
    if (colorIndex == rainbow.count) colorIndex = 0;
    self.view.backgroundColor = [rainbow objectAtIndex:colorIndex];
}
- (void)viewDidLoad{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor redColor];
    __weak PNE_ViewController *weakSelf = self;
    _observer = [[NSNotificationCenter defaultCenter] addObserverForName:backgroundColorIsGettingBoringNotification
                                                                  object:nil
                                                                   queue:[NSOperationQueue mainQueue]
                                                              usingBlock:^(NSNotification *note){
                                                                  [weakSelf observeHeyNotification:note];
                                                              }];
}
-(void)viewDidUnload{
    [super viewDidUnload];
    [[NSNotificationCenter defaultCenter] removeObserver:_observer];
}
-(void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:_observer];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end

这个 API 的主要优点似乎是你的观察块将在postNotification...称呼。如果您使用标准 API 并实施observeHeyNotification:如下所示,无法保证执行调度块之前需要多长时间:

-(void)observeHeyNotification:(NSNotification *)note{
    dispatch_async(dispatch_get_main_queue(), ^{
        // Same stuff here...
    });
}

当然,在此示例中,您可以简单地不在后台线程上发布通知,但是如果您使用的框架无法保证它将在哪个线程上发布通知,那么这可能会派上用场。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NSNotification 与dispatch_get_main_queue 的相关文章

  • Swift - 向每个页面添加相同的导航栏项目

    我正在尝试将相同的导航栏项目添加到应用程序中的每个选项卡 我目前已在我的 homeController 中正确设置了它们 但我想将代码移动到一个单独的文件中 并在我想要的任何地方远程实现它 例如 在导航栏左侧添加一个 搜索 图标 而不必在每
  • 如何使用 Swift 关闭打开的文件?

    我正在下载约 1300 张图像 这些是小图像 总大小约为 500KB 但是 下载并将它们放入 userDefault 后 我 收到如下错误 libsystem network dylib nw route get ifindex 套接字 P
  • 带过滤器的 AudioKit 导出文件

    我想用音频套件的许多过滤器覆盖现有的 m4a 文件 我的代码 file try AKAudioFile forReading recordVoiceURL player AKPlayer audioFile file delay AKVar
  • 如何在 Xcode 4.5 中添加旧版本的 iOS SDK

    我在这里复制了 iOS 5 1 SDK 应用程序 Xcode app Contents Developer Platforms iPhoneOS platform Developer SDKs 但是 我仍然无法在 Xcode 中选择基础 S
  • ViewController.swift(界面)文件的用途是什么 - 在 Counterparts 中

    我刚刚注意到一个名为ViewController swift Interface 当我创建第一个 ViewController 时 Xcode 自动创建了它 Swift 中的类是否具有 需要与 Objective C 中相同的接口 并且由
  • 如何在 swift 3 中发布原始数据?

    如果我使用 Postman 发布原始数据 就会收到响应 我正在使用这个代码 var dict Dictionary
  • 外围 BLE 设备的唯一标识符

    所以我有外围设备BLE设备 我需要一些标识符以便稍后与另一部 iPhone 共享 我连接的示例iPhone A 为外围设备 iPhone A 将外围设备的标识符保存到数据库中 稍后我可以轻松获取iPhone B 并连接到通过该标识符找到的外
  • 尽管遵循以下说明,PWA iOS Splash 仍不显示

    我正在制作 PWA 并尝试显示闪屏 我正在关注这个教程 https developer apple com library archive documentation AppleApplications Reference SafariWe
  • 记录使用 OpenAL 播放的样本

    我在 iOS 上使用 OpenAL 同时播放 9 个循环 为了使循环 100 同步 它们开始在不同的线程上运行 有关使用 OpenAL 记录正在播放的内容的任何指示 教程 如果我使用不同的线程 我会遇到录制问题吗 iOS 上的 OpenAL
  • scrollToRowAtIndexPath:atScrollPosition:动画滚动太慢

    基于分页 UIScrollView 的页面更改 我正在调用scrollToRowAtIndexPath atScrollPosition animated到所显示的该页面的表详细信息 void scrollViewDidScroll UIS
  • 未安装的应用程序的URL方案

    简单的问题 我正在开发一个将注册自己的 URL 方案的应用程序 我计划通过人们最喜欢的 QRCode 阅读器使用 QRCode 启动该应用程序 我的问题 如果我的应用程序尚未安装在他们的 iPhone iPad 上 会发生什么 他们会被引导
  • 获取 Swift 子目录中资源的所有 URL

    我正在尝试为 iOS 应用程序的子目录中的所有资源创建 URL 数组 我似乎无法到达正确的路径 即使我不知道名称 我也希望能够检索 URL 即我不想将文件名硬编码到代码中 Below is a screen shot of the hier
  • 子视图控制器旋转方法未被调用

    Summary 我试图将子视图控制器添加到父视图控制器 并让父视图控制器通知子视图控制器旋转事件 但是 旋转消息不会转发到子视图控制器 这是默认行为 为什么这种默认行为没有发生 环境 iOS 7 XCode 5 OSX 10 9 Detai
  • iOS:addConstraints:应用程序崩溃

    Problem 我似乎无法在现有项目中采用自动布局 Details 我之前也遇到过与此问题相同的问题presentViewController 在 iOS 但所提供的答案都不是我的解决方案 我正在使用所有没有 xib 的故事板视图 我的 使
  • 即时将图像添加到 AR 资源以进行图像识别

    ARKit1 5介绍图像识别 在代码中 您必须创建一组参考图像 如下所示 let referenceImages ARReferenceImage referenceImages inGroupNamed AR Resources bund
  • iOS 11 getUserMedia 不起作用?

    苹果公司发表声明称getUserMedia将在 iOS 11 上完全正常运行 安装 iOS 11 Beta 版本 5 后 我确实收到一条消息 表明我的网站请求访问我的相机和麦克风 但似乎是这样的 video src window URL c
  • AVAudioMixerNode pan 或 AVAudioUnitSamplerstereoPan 属性无法更改 AVAudioEngine 声音输出的左/右平衡

    我有以下代码 它播放单个 MIDI 音符 但我希望能够调整平衡 平移 以便它仅从左扬声器或右扬声器或某些组合中播放 我认为更改 sampler stereoPan 或 engine mainMixerNode pan 也许可以解决问题 但它
  • 如何在 XCode5 中将部署目标更改为 5.1.1 [重复]

    这个问题在这里已经有答案了 我正在一个项目中工作 我需要支持 iOS 5 1 1 但在 部署目标 的下拉菜单中我没有 5 1 1 作为选项 我的问题是如何将 iOS 5 1 1 添加为部署目标 我将非常感谢你的帮助 如果您愿意 您可以在框中
  • Swift 3 和 Xcode8 - init 的使用不明确

    在我安装 Xcode 8 并将项目转换为 Swift 3 之前 以下行没问题 现在转换后看起来像这样 let valueData Data Data bytes UnsafePointer
  • 如何将 NSAppTransportSecurity 添加到 Cordova 项目

    我正在从事一个 ionic cordova 项目 该应用程序需要配置 iOS 9 版本的应用程序传输安全例外 有谁知道如何将以下配置添加到 cordova 项目配置文件中 配置 xml

随机推荐