Skip to content
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

changed unowned to weak for unsafe situations #9

Closed
wants to merge 1 commit into from

Conversation

jpalten
Copy link
Contributor

@jpalten jpalten commented Jun 15, 2018

Using unowned self in async calls or closures can cause crashes or memory leaks. This pull requests fixes most of those unowned self to use weak self, which is much safer in most situations. Hope it helps!

  • changed unowned to weak for unsafe situations
  • extract method tryToEstablishConnection() from Session

extract method tryToEstablishConnection() from Session
Copy link
Owner

@Frugghi Frugghi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Could you limit it to the existing [unowned self], please?

// Suspend the timer to prevent calling completion two times
self.timeoutSource!.suspend()
self?.timeoutSource!.suspend()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having an optional everywhere, can you do something like this?

socketSource.setEventHandler { [weak self] in
    guard let command = self else {
        return
    }
    
    // Suspend the timer to prevent calling completion two times
    command.timeoutSource!.suspend()

    // [...]
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, or I can call it strongSelf, that is quite common as well. Take your pick!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind the name! I usually use strongSelf, so I'm happy with that 😄

@@ -54,11 +54,15 @@ public class SSHCommand<T: RawLibrary>: SSHChannel<T> {
socketSource.cancel()
}

self.queue.async {
super.close()
self.queue.async { [weak self] in
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think self should be retained by the block here, and in all the other places where you've added it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that would be great but causes retain cycles and memory leaks. Here is some explanation:
http://katalisha.com/2016/01/22/ARC-Swift-closures-and-weak-self.html
http://www.thomashanning.com/retain-cycles-weak-unowned-swift/

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware that it's a retain cycle but eventually the block will be executed and the strong reference will disappear. This allow you do to something like this:

// [...]
channel.disconnect {
    print("Disconnected")
}
channel = nil

With you change, channel would be released right away without waiting for the disconnection to complete.

@jpalten
Copy link
Contributor Author

jpalten commented Jun 16, 2018

I'll create a PR for only the unowned, and will do a little research on the unspecified strong references in closures. I'm not entirely sure that the self will ever get released, even after the block got executed. I'll get back to you on that...

@Frugghi
Copy link
Owner

Frugghi commented Jun 18, 2018

I'm going to merge the other one, thanks!

@Frugghi Frugghi closed this Jun 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants