使用通知作为回调有问题吗?
Problems using notifications as a callback?
我正在尝试在另一个 class 中发生某些事情时更新视图,经过一番查看后,似乎最常见的方法是使用委托或块来创建回调。但是,我能够使用通知完成此任务。我想知道的是:使用通知触发方法调用是否有问题?有没有我不知道的风险?我想在通知上使用 blocks/delegates 有什么原因吗?
我是 Objective-C 的新手,所以我不确定我采用的方法是否正确。
例如,我正在尝试在 ViewController 上设置 BLE 设备的电池电量。我有一个 BluetoothLEManager,它发现外围设备,它的 services/characteristics,等等。但要做到这一点,我需要在细节 ViewController 中启动 "connection",然后在我更新电池电量后找到它。
这是我正在做的一些示例代码:
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;
}
BluetoothLEManager.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];
}
...
如果您需要任何其他代码,请告诉我,但这是所有内容的基础。
每种方法都有不同的优点和缺点。
委托和协议需要在对象和它的委托之间定义一个接口,一对一的关系,并且该对象对它要调用的委托对象有特定的了解。
带有完成块的方法涉及对象与调用该方法的对象之间类似的一对一关系。但是,由于块继承了定义它们的范围,因此对于完成块中可用的上下文,您具有更大的灵活性。块还允许调用者在调用发生的同一位置定义完成代码,使您的代码更加自我记录。
在这两种情况下,通知委托或调用完成块的对象必须知道它在与谁交谈,或者正在执行什么代码。
代表电话就像汽车修理厂给您回电,让您知道您的车已经修好了。服务经理必须知道您的 phone 号码,并且知道您想要打电话。
块更像是你给厨师的食谱。给厨师不同的食谱,he/she 会为您执行不同的任务。
通知的耦合度要低得多。这就像一个城市公告员,在拥挤的 public 广场上大喊大叫。哭泣者不需要知道谁在听,或者有多少人在听。
同样,当您发送通知时,您不知道谁(如果有人)正在收听,或者有多少听众。你不需要知道。如果有 10 个对象关心你正在广播的消息,他们都可以收听,他们都会收到通知。消息发送者不必知道或关心谁在听。
有时你想要更紧密的耦合,有时你想要更松散的耦合。这取决于您要解决的问题。
我正在尝试在另一个 class 中发生某些事情时更新视图,经过一番查看后,似乎最常见的方法是使用委托或块来创建回调。但是,我能够使用通知完成此任务。我想知道的是:使用通知触发方法调用是否有问题?有没有我不知道的风险?我想在通知上使用 blocks/delegates 有什么原因吗?
我是 Objective-C 的新手,所以我不确定我采用的方法是否正确。
例如,我正在尝试在 ViewController 上设置 BLE 设备的电池电量。我有一个 BluetoothLEManager,它发现外围设备,它的 services/characteristics,等等。但要做到这一点,我需要在细节 ViewController 中启动 "connection",然后在我更新电池电量后找到它。
这是我正在做的一些示例代码:
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;
}
BluetoothLEManager.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];
}
...
如果您需要任何其他代码,请告诉我,但这是所有内容的基础。
每种方法都有不同的优点和缺点。
委托和协议需要在对象和它的委托之间定义一个接口,一对一的关系,并且该对象对它要调用的委托对象有特定的了解。
带有完成块的方法涉及对象与调用该方法的对象之间类似的一对一关系。但是,由于块继承了定义它们的范围,因此对于完成块中可用的上下文,您具有更大的灵活性。块还允许调用者在调用发生的同一位置定义完成代码,使您的代码更加自我记录。
在这两种情况下,通知委托或调用完成块的对象必须知道它在与谁交谈,或者正在执行什么代码。
代表电话就像汽车修理厂给您回电,让您知道您的车已经修好了。服务经理必须知道您的 phone 号码,并且知道您想要打电话。
块更像是你给厨师的食谱。给厨师不同的食谱,he/she 会为您执行不同的任务。
通知的耦合度要低得多。这就像一个城市公告员,在拥挤的 public 广场上大喊大叫。哭泣者不需要知道谁在听,或者有多少人在听。
同样,当您发送通知时,您不知道谁(如果有人)正在收听,或者有多少听众。你不需要知道。如果有 10 个对象关心你正在广播的消息,他们都可以收听,他们都会收到通知。消息发送者不必知道或关心谁在听。
有时你想要更紧密的耦合,有时你想要更松散的耦合。这取决于您要解决的问题。