【问题标题】:Problems using notifications as a callback?使用通知作为回调的问题?
【发布时间】:2015-02-07 00:56:31
【问题描述】:

我正在尝试在另一个类中发生某些事情时更新视图,经过一番查看后,最常见的方法似乎是使用委托或块来创建回调。但是,我能够使用通知来完成这项任务。我想知道的是:使用通知触发方法调用有问题吗?有没有我不知道的风险?我是否有理由想在通知上使用块/代表?

我是 Objective-C 的新手,所以我不确定我采用的方法是否正确。

例如,我正在尝试在 ViewController 上设置 BLE 设备的电池电量。我有一个 BluetoothLEManager,它可以发现外围设备、它的服务/特性等。但要做到这一点,我需要在 detailViewController 中启动“连接”,然后在找到它后更新电池电量。

这是我正在做的一些示例代码:

DetailViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.
    NSLog(@"Selected tag UUID: %@", [selectedTag.tagUUID UUIDString]);
    tagName.text = selectedTag.mtagName;
    if(selectedTag.batteryLevel != nil){
         batteryLife.text = selectedTag.batteryLevel;
    }

    uuidLabel.text = [selectedTag.tagUUID UUIDString];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setBatteryLevel:) name:@"SetBatteryLevel" object:nil];
}
...
-(void)setBatteryLevel:(NSNotification*)notif{
    NSMutableString* batLevel = [[NSMutableString alloc]initWithString:[NSString stringWithFormat:@"%@", selectedTag.batteryLevel]];
    [batLevel appendString:@" %"];
    selectedTag.batteryLevel = batLevel; 
    batteryLife.text = selectedTag.batteryLevel;
}

蓝牙LEManager.m:

...
-(void) getBatteryLevel:(CBCharacteristic *)characteristic error:(NSError *)error fetchTag:(FetchTag *)fetchTag
{
    NSLog(@"Getting battery Level...");
    NSData* data = characteristic.value;
    const uint8_t* reportData = [data bytes];
    uint16_t batteryLevel = reportData[0];
    selectedTag.batteryLevel = [NSString stringWithFormat:@"%i", batteryLevel];
    NSLog(@"Battery Level is %@", [NSString stringWithFormat:@"%i", batteryLevel]);
    [[NSNotificationCenter defaultCenter] postNotificationName:@"SetBatteryLevel" object:nil]; 


}
...

如果您需要任何其他代码,请告诉我,但这是一切的基础。

【问题讨论】:

  • NSNotification 而不是块/委托的问题是 NSNotification 是全局的。你不知道谁在听,也不知道接收者是否还在记忆中。一旦你发送了 NSNotification,你就不知道它是否被接收了。但是,使用块/委托,您可以确切地知道要将其发送给谁,并在您的委托上调用 selector。 NSNotifications 更多地用于全局事物,但如果您想要有针对性的东西,它不如委托/块那么干净。
  • 您应该研究第三种方法,即键值观察 (KVO),它是可可(和可可触摸)最棒和最强大的功能之一。

标签: ios objective-c callback notifications bluetooth-lowenergy


【解决方案1】:

每种方法都有不同的优点和缺点。

委托和协议需要在对象和它的委托之间定义一个接口,一对一的关系,并且对象对它要调用的委托对象有特定的了解。

具有完成块的方法涉及对象与调用该方法的对象之间类似的一对一关系。但是,由于块继承了定义它们的范围,因此您对完成块中可用的上下文具有更大的灵活性。块还允许调用者在调用发生的同一位置定义完成代码,使您的代码更具自我记录性。

在这两种情况下,通知委托或调用完成块的对象都必须知道它正在与谁交谈,或者正在执行什么代码。

代表电话就像汽车商店给您回电话,让您知道您的汽车已经完工。服务经理必须知道您的电话号码,并且知道您需要一个电话。

块更像是你给厨师的食谱。给厨师一个不同的食谱,他/她会为你执行不同的任务。

通知的耦合度要低得多。这就像一个城镇报刊员,在拥挤的公共广场上大喊大叫。哭泣者不需要知道谁在听,或者有多少人在听。

同样,当您发送通知时,您不知道谁(如果有的话)正在收听,或者有多少听众。你不需要知道。如果有 10 个对象关心您正在广播的消息,他们都可以收听,并且都会收到通知。消息发送者不必知道或关心谁在收听。

有时您想要更紧密的耦合,有时您想要更松散的耦合。这取决于您要解决的问题。

【讨论】:

  • 感谢您的回答。这真的让我对事情有了正确的认识,并帮助我理解了这些差异。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
相关资源
最近更新 更多