2015-07-02 17 views
0

我有一个闭包数组,在一个类中(我声明这是一个UIViewController是一个表视图),并且想要设置动作为我的一个单元格基于闭包。这是我的代码:Swift数组的闭包,'Int'不是'()的子类型

 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

嗯,想一想:

  • actionItem是一个函数,接受一个int并返回void。

  • actionItem(0)是对该功能的调用,所以它一个Void。

  • 所以{actionItem(0)}是一个匿名函数(一个闭包,你称之为),它带有Void并返回Void。

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

坦率地说,我不明白这与关闭有什么关系!正如你在评论中同意的,你的目标是:“我有5个按钮,我需要第一个按钮,当点击时,切换数组中的第一个项目,第二个按钮切换数组中的第二个项目, 等等。”

所以我会做的是:我会简单地给每个按钮添加标签 - 比如说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] = "___"; 
    } 
} 
+0

谢谢你的明确解释,这是非常有道理的。所以解决办法就像@Antonio建议有一个Void-> Void数组? – BHendricks

+0

我的问题是,我没有你想要做的事情的世俗观念。为什么你会想要一个闭包数组,每个闭包包含一个已经被调用__的_function?你是否知道你在做什么? :) – matt

+0

我想切换下拉列表和实际值(这是3个字符串)之间的字符串的PickRoles数组。我将这些操作附加为每个按钮的目标操作操作。这有任何意义吗? – BHendricks

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

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

要完成什么@马特评论说,这是我的目标(有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数组中简单切换它的各个元素即可。

+1

我想你是在想这个。我编辑了我的答案,以显示不涉及任何“封闭”的方法。 – matt

+0

我实际上已经掌握了所有使用这些闭合装置的工作,但我看到了您的方法的优雅。如果我有时间重构,我会用你的方式去,但我的方式似乎现在工作:) – BHendricks

+0

我很抱歉,你觉得这样。你的代码可能“有效”这一事实并不是一个明智的做法。任何时候你手动重复和计数 - actionItem(0),actionItem(1),... - 这是一个非常糟糕的代码味道。 – matt

相关问题