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

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

问题描述:

我有一些Swift代码可以与Objective C互操作,并且我注意到我在泄漏,我将其缩小到NSMutableArray而不是删除我的闭包,这里是一个纯粹的斯威夫特片段,重现了这个问题:将Swift闭包对象添加到NSMutableArray,然后删除它不起作用 - 泄露

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

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

有没有人遇到过 - 为什么会发生这种情况?我怎样才能使它工作?

+2

我无法工作,因为封闭无法比较相等:https://*.com/questions/24111984/how-do-you-test-functions-and-closures-for-equality。 - 在Q&A中也有可能的解决方法,例如将闭包封装在处理程序类中。 –

+0

谢谢你,想着做你的建议,然后改变我的API如下 - 将闭合添加到数组的方法返回其索引,并从数组中删除它的方法使用前一个方法返回的索引。 –

为了再次强调,我们的代码库使用了与ObjC互相干扰的Swift,因此,在我的情况下,它不可能纯粹地使用Swift。

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

该API的目的是注册侦听器回调,并有一个设备来注销它们。这样NSUInteger句柄满足去除位。

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

您的代码

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类。

+0

感谢您的建议,但这种解决方案对于这种情况并不好,因为约束是存在无法移除的现有ObjC互操作。 –

+0

你有官方文档吗? –

+0

这是我正在编写的代码库中的一个内部需求 –