使用Swift闭包与Objective-C框架

5

我正在使用MCSwipeTableViewCell框架来实现可滑动的tableviewcell。在cellForRowAtIndexPath函数中,其中一个完成块看起来像这样:

[cell setSwipeGestureWithView:checkView color:greenColor mode:MCSwipeTableViewCellModeSwitch state:MCSwipeTableViewCellState1 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
      // run some function call
}];

我使用了一个桥接头文件将该框架导入到我的Swift项目中,并尝试在Swift中使用相同的完成块。这是我的代码:

cell.setSwipeGestureWithView(crossView, color: UIColor.colorFromRGB(RED), mode: MCSwipeTableViewCellMode.Switch, state:MCSwipeTableViewCellState.State1, completionBlock: { (cell: MCSwipeTableViewCell!, state: MCSwipeTableViewCellState!, mode: MCSwipeTableViewCellMode!) -> Void in
    self.runSomeFunction();
});

问题在于,每次运行self.runSomeFunction()时它都会崩溃,尽管函数调用已经实现。错误信息为“未识别的选择器”。
sent to instance 0x165c7390
2014-07-07 16:23:14.809 pong[3950:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM runSomeFunction]: unrecognized selector sent to instance 0x165c7390'

我知道完成块有效,因为我可以从中进行NSLog,并且它会显示一些内容,但尝试访问self总是导致崩溃。

有什么建议吗?我不应该尝试访问self吗?

=== 更新 ===

主要我要弄清楚的是如何在Swift闭包中访问self,它始终会抛出错误。

这是正在运行的代码

 func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
    var cell = tableView.dequeueReusableCellWithIdentifier("userCell") as MCSwipeTableViewCell!

    if !cell {
        cell = MCSwipeTableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "userCell")
     }
    cell.setSwipeGestureWithView(crossView, color: UIColor.colorFromRGB(RED), mode: MCSwipeTableViewCellMode.Switch, state:MCSwipeTableViewCellState.State1, completionBlock: { (cell: MCSwipeTableViewCell!, state: MCSwipeTableViewCellState!, mode: MCSwipeTableViewCellMode!) -> Void in
        self.runSomething();
    });
    return cell
}

 func runSomething()
{
    NSLog("hey there");
}

那与此无关。这不是编译时问题。 - Jack Lawrence
是的,添加一个 return void() 是没有任何作用的。它仍然会在那里崩溃,现在除了 exc_bad_access 之外不会打印任何东西。 - Brian Weinreich
"MyClass.runSomeFunction()" 不是 Objective-C,与 "self.runSomeFunction()" 非常不同。 - Darren
啊,抱歉,我刚在写 Ruby 代码时有些困惑。我已经更新了问题并删除了那部分内容。我正在尝试在 UIViewController 上调用一个私有方法。 - Brian Weinreich
1
-[__NSArrayM runSomeFunction]: unrecognized selector sent to instance 这个错误提示告诉你,你可能认为自己在访问 self,但实际上是在访问一个 NS(Mutable)Array。也许是内存问题? - Jack Lawrence
好了,我不再遇到那个错误了。我尝试在块中传递对 self 的强引用,但即使这样也会崩溃,除了 EXC_BAD_ACCESS 之外没有任何显著的错误。 - Brian Weinreich
2个回答

2
你可以定义一个捕获列表,像这样在闭包中使用self: Capture List
cell.setSwipeGestureWithView(crossView, color: UIColor.colorFromRGB(RED), mode: MCSwipeTableViewCellMode.Switch, state:MCSwipeTableViewCellState.State1) {
    [unowned self]
    cell, state, mode in
    self.runSomething()
}

当前 [unowned self] 有时可能会崩溃,因此暂时使用 [weak self],在闭包内部解包 self,例如: self!.doSomething()


0

首先,您需要通过[weak self]来弱化self。然后在块内尝试检查self是否不为nil

if let weakSelf = self {
   // do whatever you want with the self
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接