Weak property deallocation confusion


Weak property deallocation confusion



I'm using a third party library and it required setting a delegate. In this scenario I want to set the delegate to be another class so I go to write


ThirdPartyLibrary.delegate = MyDelegateHandlerClass()



But Xcode (Xcode 10 beta) gives me a warning saying:



Instance will be immediately deallocated because property ‘delegate’
is ‘weak’



Clicking into the delegate of the third party library I see that it is indeed defined as weak as follows:


delegate


weak


@property (weak, nonatomic) id<ThirdPartyLibraryDelegate> delegate;



However, if I change my initial setting of the delegate to:


let someInstance = MyDelegateHandlerClass()
ThirdPartyLibrary.delegate = someInstance



Then I get no warning? How are these two not the same thing? Just looking for advice and an explanation really. Thanks!





For anyone interested, this warning was recently implemented in github.com/apple/swift/pull/14875 :)
– Hamish
Jun 29 at 12:18




2 Answers
2



They are, in effect, the same thing. Once someInstance goes out of scope the delegate handler will be released and the delegate property of the library will become nil.


someInstance


nil



In the first case the compiler can see that the result of an allocation is being assigned to a weak property and warn you that it will be immediately released, which is probably not what you want.


weak



In the second case it sees the assignment to a local variable and so the object will remain in memory for some time. The compiler cannot determine that you didn't want the object to be released at the end of the function, which means that it doesn't warn you.



You will need to store a strong reference to the delegate handler in a property





Ah makes sense! Now let's say all of this is going on in a struct, at the top of the struct I could just declare private static let someInstance = MyDelegateHandlerClass() and then assign that to the delegate and that would be ok?
– Mr.P
Jun 29 at 10:50


private static let someInstance = MyDelegateHandlerClass()


delegate





Yes, that would work.
– Paulw11
Jun 29 at 10:51



You get no warning in second case, but it will get deallocated as well, because someInstance is a local variable - will be deallocated when you leave the scope where it was declared.


someInstance



What you need to do is store your MyDelegateHandlerClass instance somewhere. If you are certain that you will use only one instance of MyDelegateHandlerClass, you can use a Singleton pattern:


MyDelegateHandlerClass


MyDelegateHandlerClass


class MyDelegateHandlerClass : ThirdPartyLibraryDelegate
{
static let sharedInstance = MyDelegateHandlerClass()

// class implementation
}

(...)

ThirdPartyLibrary.delegate = MyDelegateHandlerClass.sharedInstance






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV