-1

I have some Swift code that interoperates with Objective C, and I noticed I'm leaking, I narrowed it down to NSMutableArray not removing my closure, here's a pure Swift snippet that reproduces the problem:

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

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

Did anyone encounter this -- why does this happen? and how can I get it to work?

Max Raskin
  • 1,042
  • 1
  • 14
  • 26
  • 2
    I cannot work because closures cannot compared for equality: https://stackoverflow.com/questions/24111984/how-do-you-test-functions-and-closures-for-equality. – There are also possible workarounds in that Q&A, such as wrapping the closure in a handler class. – Martin R Sep 14 '17 at 09:01
  • Thanks, thought about doing what you suggested, then changed my API as follows - the method that adds the closure to the array returns its index, and the method that removes it from the array uses the index returned by the previous method. – Max Raskin Sep 14 '17 at 12:22

2 Answers2

1

The closure doesn't have the reference so the array is unable to compare for removing your closure object that's why this will not remove from the array.

Your code

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

Solution

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

This will remove by index so you have to use the index for removing the element instead of closure instance also I recommend you to use pure swift classes in Swift.

Salman Ghumsani
  • 3,647
  • 2
  • 21
  • 34
-1

To re-emphasize, our codebase uses Swift that interops with ObjC, therefore, in my case its not possible to go pure Swift trivially.

I changed our API to use an NSDictionary that maps from NSUInteger handle to the closure and that integer is then used for removal of the closure from the dictionary.

The purpose of that API is to register listener callbacks and have a facility to unregister them. So that NSUInteger handle satisfies the removal bit.

Max Raskin
  • 1,042
  • 1
  • 14
  • 26