Swift - 具有自引用的变量函数

时间:2016-11-28 20:05:55

标签: ios swift

我已经制作了一个结构来保存我的UITableViewCell的数据,如下所示:

struct CellData {
    var title: String
    var action: () -> Void
    init(title: String, action: () -> Void) {
        self.title = title
        self.action = action
    }
}

在我的TableViewController中,我将其设置为:

lazy var buttonCells: [CellData] = [
    CellData(
        title: "Button 1",
        action: {
            **self.doSomething()**
        }
    ),
    CellData(
        title: "Button 2",
        action: {
            **self.doSomethingElse()**
        }
    )
]

但是,在操作中使用self会导致TableViewController在控制器被解除时deinitialized不是deinitself功能不是&{ #39; t叫)。当我删除TableViewController个引用,并将其替换为其他内容时,deinitialized就是 <script type="text/javascript"> function msgCounter(txtField, msgCount) { if (txtField.value.length <= 160) { msgCount.value = "1/6"; } else if (txtField.value.length > 160 && txtField.value.length < 321) { msgCount.value = "2/6"; } else if (txtField.value.length > 320 && txtField.value.length < 481) { msgCount.value = "3/6"; } else if (txtField.value.length > 480 && txtField.value.length < 641) { msgCount.value = "4/6"; } else if (txtField.value.length > 640 && txtField.value.length < 801) { msgCount.value = "5/6"; } else if (txtField.value.length > 801 && txtField.value.length < 961) { msgCount.value = "6/6"; } else { //alert("Maximum SMS number reached!"); } } </script> 就好了。我怎样才能修复这个废弃的内存问题?

2 个答案:

答案 0 :(得分:5)

更改您的操作定义以使用捕获组:

action: {
  [weak self] in

  guard let strongSelf = self else {
    return
  }
  strongSelf.doSomething()
}

[weak self]捕获组声明的作用是将self转换为块内的弱变量。如果拥有对象在块等待被调用时被释放,则它将被传递为nil。

然后,在块内部,guard语句尝试将弱自定义映射到强大的局部变量。如果self为零,则退出。如果没有,strongSelf包含一个未经包装的强引用自我,你就可以正常进行。

答案 1 :(得分:1)

强参考周期

在您的表视图控制器中,您可能正在创建这样的CellData吗?

CellData(title: "Hello") { 
    // here you are using self
}

或许你正在写这个

CellData(title: "Hello", action: {
    // here you are using self
})

在这两种情况下都存在问题,因为您正在创建强参考周期

解决方案

你可以使用这段代码来避免这种情况

CellData(title: "Hello") { [unowned self] in
    // here you can use self
}

最后一件事

只需删除结构中的init,Swift将为您提供;)

struct CellData {
    let title: String
    let action: () -> ()
}