我目前正在为React-Native的HomeKit搭建桥梁,我必须读取HomeKit值才能返回Java代码。
要读取特征的最新值,我们必须使用readValueWithCompletionHandler,直到该值完成才准备就绪。因此,我必须阅读这些特征中的6个,并将每个特征分配给我的NSMutableDictionary
对象,以返回React-Native进行处理。
与其在前一个completionHandler
内将每个读取嵌套在最后一个return accObject
内,不如在completionHandlers
之前等待所有return
完成的最干净的方法是
我一直在搜索semaphores
,DispatchGroup
和其他几个解决方案,但对如何解决这个问题却一无所知。
(粗略的)示例:
NSMutableDictionary *accObject = [[NSMutableDictionary alloc] initWithCapacity: 6];
[charac1 readValueWithCompletionHandler:^(NSError *error) {
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac1.value);
accObject[@"charac1"] = charac1.value;
}];
...
[charac6 readValueWithCompletionHandler:^(NSError *error) {
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac6.value);
accObject[@"charac6"] = charac6.value;
}];
return accObject;
答案 0 :(得分:1)
在这种情况下,我建议使用dispatch_group_t
等待读取值,并使用完成块来处理返回的值。
- (void)readValuesWithCompletionHandler:(void(^)(NSDictionary* values))completion {
NSMutableDictionary *accObject = [[NSMutableDictionary alloc] initWithCapacity: 6];
// Initialize |charac1|, |charac2|, ...
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[charac1 readValueWithCompletionHandler:^(NSError *error) {
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac1.value);
accObject[@"charac1"] = charac1.value;
dispatch_group_leave(group);
}];
// ... Do same thing with another values
dispatch_group_enter(group);
[charac6 readValueWithCompletionHandler:^(NSError *error) {
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac6.value);
accObject[@"charac6"] = charac6.value;
dispatch_group_leave(group);
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
if (completion) {
completion(accObject);
}
});
}
用法:
[self readValuesWithCompletionHandler:^(NSDictionary *values) {
// Do whatever you want with |values| after reading
}];
答案 1 :(得分:1)
您可以在等待dispatch_semaphore_wait()
的情况下使用dispatch_semaphore_t
您可以使用此过程为我完成这项工作。
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableDictionary *accObject = [[NSMutableDictionary alloc] initWithCapacity: 6];
[charac1 readValueWithCompletionHandler:^(NSError *error) {
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac1.value);
accObject[@"charac1"] = charac1.value;
}];
...
[charac6 readValueWithCompletionHandler:^(NSError *error) {
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac6.value);
accObject[@"charac6"] = charac6.value;
}];
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return accObject;
答案 2 :(得分:0)
认为我已经找到了基于this article的解决方案。
NSMutableDictionary *accObject = [[NSMutableDictionary alloc] initWithCapacity: 6];
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[charac1 readValueWithCompletionHandler:^(NSError *error) {
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac1.value);
accObject[@"charac1"] = charac1.value;
dispatch_group_leave(group);
}];
...
dispatch_group_notify(serviceGroup,dispatch_get_main_queue(),^{
// Now call the final completion block
return accObject;
});
答案 3 :(得分:0)
您可以在此处使用调度组,即不能返回值,但可以调用完成块。该完成块可以作为函数的参数存在。
NSMutableDictionary *accObject = [[NSMutableDictionary alloc] initWithCapacity: 6];
dispatch_group_t group = dispatch_group_create();
[charac1 readValueWithCompletionHandler:^(NSError *error) {
dispatch_group_enter(group);
if (error) {
RCTLog(@"ERROR READING HOMEKIT VALUE: %@", error);
}
RCTLog(@"READ SETPOINT VALUE: %@", charac1.value);
accObject[@"charac1"] = charac1.value;
dispatch_group_leave(group);
}];
...
dispatch_group_notify(serviceGroup,dispatch_get_main_queue(),^{
// Now here instead of returning a value, you can call a completion handler.
});