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

PublishSubject onCompleted from different disposeBag #1439

Closed
grinder81 opened this issue Oct 7, 2017 · 7 comments
Closed

PublishSubject onCompleted from different disposeBag #1439

grinder81 opened this issue Oct 7, 2017 · 7 comments

Comments

@grinder81
Copy link

Short description of the issue:

Wrong disposeBag triggering onComplete for another publish subject.

Explanation:

So far this is the weirdest problem I'm dealing with my project using RxSwift. Here are the details:

Publish Subject holder class:

class MyPublishHolder: NSObject{
	
	static let shared = MyPublishHolder()

	let actionPublishSubject = PublishSubject<SomeEnum>()
}

Class subscribing publish subject:

class MyPublishSubscriber: NSObject {
	
	static let shared = MyPublishSubscriber()	

	// This is an Rx Initializer only get call once
	func setupRx() {

		MyPublishHolder.shared.actionPublishSubject
			.subscribeNext {( enum ) in 
				print (enum)
			})
			, onError: { (error) in
                           print(error)
                       }, onCompleted: {
                           print("onCompleted !!!!")
                     }) {
                          print("Why !!!!")
                      }
			.addDisposableTo(rx.disposeBag)
	}
}

From my other class, I'm just doing something like

MyPublishHolder.shared.actionPublishSubject
	.onNext(SomeEnum.enum)

That's it!

Problem:
Everything works fine as expected. I publish an enum and MyPublishSubscriber do some work based on that enum. But in a very certain case which is reproducible every time, onCompleted get called though I never did have onComplete call for this publish subject. Then when I started digging memory footprint I found autorelease pool clearing memory which calls deinit of a disposeBag and that's lead to onCompleted and then onDispose.

Please note that I tracked memory location of MyPublishSubscriber rx.disposeBag and then the one is getting free and this one completely different memory location or address.

Right now I don't see a way to dig more.

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

3.x

Platform/Environment

  • iOS

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

  • easy, 100% repro

Xcode version:

Xcode 9 

Installation method:

  • CocoaPods
    I have multiple versions of Xcode installed:
    (so we can know if this is a potential cause of your issue)
    7,8 and 9
@kzaher
Copy link
Member

kzaher commented Oct 7, 2017

Hi @grinder81 ,

can you please provide me with some code that reproduces this issue?

It is not clear what is .addDisposableTo(rx.disposeBag).

@grinder81
Copy link
Author

.addDisposableTo(rx.disposeBag) from another pod but please ignore that. I also replaced it by fileprivate var disposeBag = DisposeBag() in my MyPublishSubscriber class and then .addDisposableTo(rx.disposeBag) become .addDisposableTo(self.disposeBag).

@kzaher
Copy link
Member

kzaher commented Oct 7, 2017

Can you repro that in a standalone example project? If so, do you mind sending me that project?

@grinder81
Copy link
Author

I tried to create a simple project to reproduce it but that doesn't happen :( I wish I could do that.

Is there any particular area I can focus to trace it down? I have other publish subject but it doesn't happen with other cases. I tried to force it to subscribe on the main scheduler to see is that event anomaly or not but didn't help.

@kzaher
Copy link
Member

kzaher commented Oct 7, 2017

I would assume that there is a faulty rx extension somewhere.

Usually what happens is that somebody is using objc_getAssociatedObject and objc_setAssociatedObject inside rx extension in this form objc_getAssociatedObject(self, ... vs the correct objc_getAssociatedObject(base, ....

Because Swift has struct reusing, those two facts combined usually results in that kind of behavior.

I would also suggest tracing the creation of all of the subjects, printing their addresses and similar. Sorry, can't help you more without repro.

Good luck!

@kzaher kzaher closed this as completed Oct 7, 2017
@grinder81
Copy link
Author

I think you gave me the biggest hint. I have following pod

https://github.com/RxSwiftCommunity/NSObject-Rx

which is using objc_ creating mechanism. Here it is:

https://github.com/RxSwiftCommunity/NSObject-Rx/blob/master/HasDisposeBag.swift

I'm going to dig. I really appreciate your feedback and I can't expect more than that as I can't give a sample project to you.

Thanks a lot and will let you know how it ends up.

If you see anything in that pod which is bad, please let it know here.

@grinder81
Copy link
Author

Just to give an update. I did quite an investigation.

  • I removed that pod completely and made sure there is no rx.disposeBag in my code
  • Replaced rx.disposeBag by self.disposeBag

But still, I'm seeing that issue. Which means I can't blame this pod for memory leaking. I'll keep digging.

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

No branches or pull requests

2 participants