gpt4 book ai didi

ios - 防止一个闭包运行,直到另一个闭包完成

转载 作者:行者123 更新时间:2023-11-30 14:17:53 24 4
gpt4 key购买 nike

下面是两次不同的 IBAction 按钮按下时两次关闭的代码。期望的结果是按下按钮打开/关闭 LED,然后访问光传感器并在 LED 状态发生变化后读取光值。

发生的情况是,函数 getVariable 在 callFunction 实现更改之前运行并返回的竞争条件。结果是 getLightLabel.text 中显示的值是先前条件的值,而不是当前条件的值。

我的问题是如何重写下面的代码,以便 myPhoton!.getVariable 在 myPhoton!.callFunction 返回(完成其任务)之前不会执行。

我尝试将 getVariable 放在 callFunction 中,在 } 关闭 if (error == nil) 之前和之后,但结果与此处显示的代码相同。

@IBAction func lightOn(sender: AnyObject) {
let funcArgs = [1]
myPhoton!.callFunction("lightLed0", withArguments: funcArgs) { (resultCode : NSNumber!, error : NSError!) -> Void in
if (error == nil) {
self.lightStateLabel.text = "LED is on"
}
}
myPhoton!.getVariable("Light", completion: { (result:AnyObject!, error:NSError!) -> Void in
if let e = error {
self.getLightLabel.text = "Failed reading light"
}
else {
if let res = result as? Float {
self.getLightLabel.text = "Light level is \(res) lumens"
}
}
})



}


@IBAction func lightOff(sender: AnyObject) {
let funcArgs = [0]
myPhoton!.callFunction("lightLed0", withArguments: funcArgs) { (resultCode : NSNumber!, error : NSError!) -> Void in
if (error == nil) {
self.lightStateLabel.text = "LED is off"
}
}
myPhoton!.getVariable("Light", completion: { (result:AnyObject!, error:NSError!) -> Void in
if let e = error {
self.getLightLabel.text = "Failed reading light"
}
else {
if let res = result as? Float {
self.getLightLabel.text = "Light level is \(res) lumens"
}
}
})

}

这是 .h 文件中的 callFunction 注释和代码。这个 SDK 是用 Objective C 编写的。我在 Swift 中使用它并带有桥接头文件。

/**
* Call a function on the device
*
* @param functionName Function name
* @param args Array of arguments to pass to the function on the device. Arguments will be converted to string maximum length 63 chars.
* @param completion Completion block will be called when function was invoked on device. First argument of block is the integer return value of the function, second is NSError object in case of an error invoking the function
*/
-(void)callFunction:(NSString *)functionName withArguments:(NSArray *)args completion:(void (^)(NSNumber *, NSError *))completion;

/*
-(void)addEventHandler:(NSString *)eventName handler:(void(^)(void))handler;
-(void)removeEventHandler:(NSString *)eventName;
*/

这是.m文件代码

-(void)callFunction:(NSString *)functionName withArguments:(NSArray *)args completion:(void (^)(NSNumber *, NSError *))completion
{
// TODO: check function name exists in list
NSURL *url = [self.baseURL URLByAppendingPathComponent:[NSString stringWithFormat:@"v1/devices/%@/%@", self.id, functionName]];
NSMutableDictionary *params = [NSMutableDictionary new]; //[self defaultParams];
// TODO: check response of calling a non existant function

if (args) {
NSMutableArray *argsStr = [[NSMutableArray alloc] initWithCapacity:args.count];
for (id arg in args)
{
[argsStr addObject:[arg description]];
}
NSString *argsValue = [argsStr componentsJoinedByString:@","];
if (argsValue.length > MAX_SPARK_FUNCTION_ARG_LENGTH)
{
// TODO: arrange user error/codes in a list
NSError *err = [self makeErrorWithDescription:[NSString stringWithFormat:@"Maximum argument length cannot exceed %d",MAX_SPARK_FUNCTION_ARG_LENGTH] code:1000];
if (completion)
completion(nil,err);
return;
}

params[@"args"] = argsValue;
}

[self setAuthHeaderWithAccessToken];

[self.manager POST:[url description] parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (completion)
{
NSDictionary *responseDict = responseObject;
if ([responseDict[@"connected"] boolValue]==NO)
{
NSError *err = [self makeErrorWithDescription:@"Device is not connected" code:1001];
completion(nil,err);
}
else
{
// check
NSNumber *result = responseDict[@"return_value"];
completion(result,nil);
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
if (completion)
completion(nil,error);
}];

}

最佳答案

一个解决方案是将第二个闭包放入第一个闭包中,其中第一个闭包返回并提供 Error 值。如果没有错误,则执行第二次闭包。这是紧密耦合两个闭包的一种方法,无需借助信号量或其他消息传递方案。

在此应用程序中,我遇到的问题无法在堆栈的 IOS/Swift 端解决。云API和嵌入式uP并不是紧密耦合的,因此在Particle uP上运行完整的功能代码之前,云会返回到IOS并完成。

这个整体问题的解决方案实际上在于修改云 API 或向 uP 固件添加一些额外的代码,以通过额外的通信将进程与 IOS 应用程序紧密耦合。

关于ios - 防止一个闭包运行,直到另一个闭包完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30905552/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com