Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 防止关闭运行,直到另一个关闭完成_Ios_Swift_Closures - Fatal编程技术网

Ios 防止关闭运行,直到另一个关闭完成

Ios 防止关闭运行,直到另一个关闭完成,ios,swift,closures,Ios,Swift,Closures,下面是在两个不同的IBAction按钮按下中两个闭包的代码。理想的结果是按下按钮打开/关闭LED,然后访问光传感器并在LED状态改变后读取光值 所发生的是一个竞争条件,其中函数getVariable在callFunction实现更改之前运行并返回。结果是getLightLabel.text中显示的值是先前条件的值,而不是当前条件的值 我的问题是如何重写下面的代码,以便myPhoton!。getVariable在myPhoton!之后才会执行!。callFunction已返回(已完成其任务) 我曾

下面是在两个不同的IBAction按钮按下中两个闭包的代码。理想的结果是按下按钮打开/关闭LED,然后访问光传感器并在LED状态改变后读取光值

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

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

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

@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);
    }];

}

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

在这个应用程序中,我遇到的问题无法在堆栈的IOS/Swift端得到解决。cloud API和embedded uP没有紧密耦合,因此在完整的函数代码在Particle uP上运行之前,云将返回到IOS并完成


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

您确定您的问题不是代码本身吗?在这两个callFunctions中,您似乎在组合代码来定义一个函数和调用一个函数——您正在调用myPhoton!。callFunction(…),但在传递所有参数后,{…}括号中还有代码。@dunnmifflsys这是将闭包作为函数调用中的最后一个参数所能做的。foo(块:{closure})可以写为foo{closure}。我在最初的帖子中缺少的是callFunction和getVariable的定义。我们可以看看您的callFunction(quot:withArguments:)定义吗?请看相关的更改。我从Objective C SDK中添加了.h和.m文件代码。我使用Swift中的桥接头文件来访问该函数。如果有可能将解决方案局限于Swift,则首选该解决方案。