将 Swift 闭包对象添加到 NSMutableArray 然后删除它不起作用 - LEAK

Adding Swift closure object to NSMutableArray and then removing it doesn't work - LEAK

我有一些与 Objective C 互操作的 Swift 代码,我注意到我在泄漏,我将它缩小到 NSMutableArray 而不是删除我的闭包,这是一个纯粹的 Swift重现问题的片段:

let myClosure  : ((String?) -> ())! = { (fileName: String?) in
}

let arr = NSMutableArray()
arr.add(myClosure) 
arr.remove(myClosure)

有没有人遇到过这个——为什么会这样?我怎样才能让它工作?

闭包没有引用,因此数组无法比较删除闭包对象,这就是为什么它不会从数组中删除的原因。

您的代码

let arr1 = NSMutableArray()
arr1.add(myClosure)     
print(arr1)          //("(Function)")
arr1.remove(myClosure) 
print(arr1)          //("(Function)")

解决方案

var arr = Array<Any>()
arr.append(myClosure)
print(arr)          //[(Function)]
arr.remove(at: 0)
print(arr)          //[]

这将按索引删除,因此您必须使用索引而不是闭包实例来删除元素我也建议您在 Swift 中使用纯 swift 类。

再次强调,我们的代码库使用与 ObjC 互操作的 Swift,因此,在我的情况下,不可能简单地实现纯粹的 Swift。

我更改了 API 以使用从 NSUInteger 句柄映射到闭包的 NSDictionary,然后使用该整数从字典中删除闭包。

API 的目的是注册侦听器回调并具有注销它们的功能。这样 NSUInteger 句柄满足删除位。