Make self weak in methods in Swift

后端 未结 5 1999
遇见更好的自我
遇见更好的自我 2020-12-05 07:06

I have a Swift class that needs to store a table of its own methods. Unfortunately this is causing a reference cycle, because its table retains references to self

5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-05 07:53

    You can certainly build a function for this. I don't know if it makes it dramatically better, but it is less error-prone.

    func methodPointer(obj: T, method: (T) -> () -> Void) -> (() -> Void) {
      return { [unowned obj] in method(obj)() }
    }
    ...
    myCallbacks.append(methodPointer(self, CycleInducingClass.myInternalFunction))
    

    Alternately, you could manage your callbacks as method pointers:

    typealias Callback = (CycleInducingClass) -> () -> Void
    ...
    myCallbacks.append(CycleInducingClass.myInternalFunction)
    

    In that case, you'd need to pass self when you called them (which may be fine if you don't actually do this a lot):

    self.myCallbacks[0](self)()
    

    All of this is based on the fact that a method on type T with signature (input) -> (output) is equivalent to a function with the signature (T) -> (input) -> (output).

    In case you're curious (I was), overriding works correctly in this case. So if you subclass CycleInducingClass and override myInternalFunction, the correct version will be called. (That actually surprises me a little, and I don't yet know exactly why it works, but it does.)

    EDIT: Here's the answer to that: https://devforums.apple.com/message/1036509#1036509

提交回复
热议问题