我在一个类中有一个闭包数组(我在作为表视图的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 '()'
我该怎么办才能解决这个问题?
好吧,想想看:
-
actionItem
是一个接受Int并返回Void的函数。 -
actionItem(0)
是对该函数的调用,因此它是一个Void。 -
所以
{actionItem(0)}
是一个匿名函数(您称之为闭包(,它接受Void并返回Void。
好吧,您正试图将其放入(Int)->Void
的数组中。很明显,这是一个类型上的不匹配:Int输入不是Void输入。这正是编译器告诉你的。
坦率地说,我不认为这与关闭有什么关系!正如你在评论中所同意的那样,你的目标是:"我有5个按钮。当点击第一个按钮时,我希望第一个按钮切换数组中的第一个项目,第二个按钮切换阵列中的第二个项目,以此类推。">
所以我要做的是:我只需在每个按钮上贴上标签——比如说,100102103104。我会给他们每个人相同的行动方法。当调用该方法时,我们从发送方的标记中减去100。现在我们有了索引!现在我们切换数组索引的值。
func doButton(sender:UIView) {
let index = view.tag - 100
if(self.pickedRoles[index] == "___") {
self.pickedRoles[index] = self.roles[index];
} else {
self.pickedRoles[index] = "___";
}
}
有两种可能的方法来修复编译错误,但我不知道哪一种是正确的,这取决于你试图做什么。
闭包数组用无参数闭包填充:
{ 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);
}]
正如@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
数组中的相应元素。