2017-09-14 78 views
-1

我有一些Swift代碼可以與Objective C互操作,並且我注意到我在泄漏,我將其縮小到NSMutableArray而不是刪除我的閉包,這裏是一個純粹的斯威夫特片段,重現了這個問題:將Swift閉包對象添加到NSMutableArray,然後刪除它不起作用 - 泄露

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

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

有沒有人遇到過 - 爲什麼會發生這種情況?我怎樣才能使它工作?

+2

我無法工作,因爲封閉無法比較相等:https://stackoverflow.com/questions/24111984/how-do-you-test-functions-and-closures-for-equality。 - 在Q&A中也有可能的解決方法,例如將閉包封裝在處理程序類中。 –

+0

謝謝你,想着做你的建議,然後改變我的API如下 - 將閉合添加到數組的方法返回其索引,並從數組中刪除它的方法使用前一個方法返回的索引。 –

回答

-1

爲了再次強調,我們的代碼庫使用了與ObjC互相干擾的Swift,因此,在我的情況下,它不可能純粹地使用Swift。

我將API更改爲使用從NSUInteger句柄映射到閉包的NSDictionary,然後使用該整數從字典中移除閉包。

該API的目的是註冊偵聽器回調,並有一個設備來註銷它們。這樣NSUInteger句柄滿足去除位。

1

閉包沒有引用,因此數組無法進行比較以刪除閉包對象,這就是爲什麼它不會從數組中刪除。

您的代碼

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

這是我正在編寫的代碼庫中的一個內部需求 –