-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-786] addObserverForName causes a memory leak on pure swift objects #43398
Comments
What version of Swift are you using? (If in Xcode, which Xcode? If it's a beta, which beta?) @jckarter, sound familiar? |
Pure Swift weak references lazily reclaim their memory since we never implemented the side-table implementation for them. The memory won't be reclaimed until the closure is invoked. Is that what you're seeing? Note that the reference cycle should still be severed. |
Comment by Michal (JIRA) Sorry, forgot to mention: Xcode 7.2.1 Yes, that's exactly what I'm seeing. |
It shouldn't be a true leak, then, just delayed memory reclamation. We had intended to move to a more ObjC-like eager reclamation model, but that requires a slower implementation. |
Comment by Michal (JIRA) by "delayed", you mean delayed until the closure is invoked ? A good practice is to delete observers as fast as you can (willDisappear in ViewControllers for example), so most of the times the closure will not be invoked. |
Delayed until the closure is either invoked or destroyed. Releasing all of the weak references to the object should also reclaim its memory, unless that's where we have a bug. |
Comment by Michal (JIRA) Ok, that's the problem I have. I'm removing the observer in `deinit` - and naturally deinit is not being called, so the closure is not destroyed. |
OK, that's a real problem then. |
Comment by Michal (JIRA) Im testing that now. I only assumed that. |
Comment by Michal (JIRA) Ok, deinit is being called. Sorry for the confusion. The problem here is that my deinit looks like that deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
} And that's not how you remove observers that are added with "addObserverForName:usingBlock", so the closure doesn't get destroyed after all. The remaining question is: is the fact that the closure keeps the object alive in spite of [weak self] a bug, or not ? Also it's important to remember that for iOS9 it is not mandatory anymore to remove observers as it will not cause an exception to be raised. |
There's a discussion about this on swift-dev: https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151207/000253.html We had planned to eventually move to a more ObjC-like implementation, but @mikeash made some arguments for keeping the current implementation model (with fixes for some concurrency problems he discovered). Problems like this might necessitate us sticking to the original plan. |
Comment by Michal (JIRA) Ok, please change the state of this ticket to whatever you see fit 🙂) Thanks! |
Is this resolved, or no longer valid? If either, this should be closed. |
Additional Detail from JIRA
md5: e5d782af342b2ec76296a7751f32a0e3
Issue Description:
If "self" is a pure swift object (not NSObject) it'll cause the closure/block to retain self in spite of it being declared as weak. It caused a memory leak in my classes that were pure swift and worked propery in my NSObject classes.
The text was updated successfully, but these errors were encountered: