【发布时间】: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