Swift一系列的闭包,' Int'不是'()'

时间:2015-07-02 18:07:03

标签: ios arrays swift

我在一个类中有一个闭包数组(我在一个UIViewController中声明这是一个表视图),并希望根据闭包设置我的一个单元格的动作。这是我的代码:

        var actionItem : (Int)->Void = {
            (index: Int)->Void in
            if(self.pickedRoles[index] == "___") {
                self.pickedRoles[index] = self.roles[index];
            } else {
                self.pickedRoles[index] = "___";
            }
        }

        var roleActions : Array<(Int)->Void> = [{
                actionItem(0);
            }, {
                actionItem(1);
            }, {
                actionItem(2);
            }, {
                actionItem(3);
            }, {
                actionItem(4);
        }];

actionItem是我的闭包,pickedRoles是一个类变量,它是一个字符串数组,类似于roles。我希望roleActions表示用户选择角色时会发生什么,但在声明roleActions的行中,我收到错误消息:

'Int' is not a subtype of '()'

我该怎么做才能解决这个问题?

3 个答案:

答案 0 :(得分:3)

好吧,想一想:

  • actionItem是一个接受Int并返回Void的函数。

  • actionItem(0)是对该函数的调用,因此 是一个虚空。

  • 所以{actionItem(0)}是一个匿名函数(一个闭包,就像你所说的那样),它接受Void并返回Void。

好吧,你试图把它放到(Int)->Void的数组中。显然,这是一种类型不匹配:Int输入不是Void输入。这正是编译器告诉你的。

坦率地说,我不知道这与封闭有什么关系!您在评论中同意的目标是:&#34;我有5个按钮。我想要第一个按钮,当点击时,切换数组中的第一个项目,第二个按钮切换数组中的第二个项目,依此类推。&#34;

所以我要做的是:我只是将标签附加到每个按钮 - 比如100,101,102,103,104。我会给他们每个相同的动作方法。调用该方法时,我们从发件人的标签中减去100。现在我们有了索引!现在我们切换数组索引的值。

func doButton(sender:UIView) {
    let index = view.tag - 100
    if(self.pickedRoles[index] == "___") {
        self.pickedRoles[index] = self.roles[index];
    } else {
        self.pickedRoles[index] = "___";
    }
}

答案 1 :(得分:1)

有两种方法可以修复编译错误,但我不知道哪一种是正确的,具体取决于你要做的事情。

闭包数组用无参数闭包填充:

{ Void -> Void in actionItem(0) }

因此数组声明不正确,包含的类型应为Void -> Void - 固定代码为:

var roleActions : Array<Void -> Void> = [{
        actionItem(0);
    }, {
        actionItem(1);
    }, {
        actionItem(2);
    }, {
        actionItem(3);
    }, {
        actionItem(4);
}]

或者,如果数组中包含的元素类型是正确的,则基于您的应用程序逻辑,您只需使用_ in跳过传递给每个闭包的整数参数:

var roleActions : Array<Int -> Void> = [{
        _ in actionItem(0);
    }, {
        _ in actionItem(1);
    }, {
        _ in actionItem(2);
    }, {
        _ in actionItem(3);
    }, {
        _ in actionItem(4);
}]

答案 2 :(得分:0)

正如@matt和@Antonio建议的那样,我最初的方法是错误的,但为了最终获得理想的行为,我不得不比他们的任何一个解决方案更进一步。

要完成@matt所评论的内容,这是我的目标(有5个按钮,其中每个按钮切换数组中的元素),我必须使用以下代码:

         var actionItem : ((Int)->(Void->Void)) = {
            (index: Int) in
            return {
                if(self.pickedRoles[index] == "___") {
                    self.pickedRoles[index] = self.roles[index];
                } else {
                    self.pickedRoles[index] = "___";
                }
            };
        }

        var roleActions : [Void->Void] = [actionItem(0), actionItem(1), actionItem(2), actionItem(3), actionItem(4)];

这给了我一个闭包数组,其中每个闭包都可以不带参数调用,只需切换它在pickedRoles数组中的相应元素。