For example viewWillAppear on UIViewController or prepareForReuse on UITableViewCell and ..HeaderView
Hi @sergdort ,
We don't officially support out of the box observing of method calls :)
People usually have some kind of base classes for their projects, so in that base class you just expose PublishSubject called onPrepareForReuse (or something like that), override onPrepareForReuse and call .on(.Next()).
So far I see that as a preferred way over swizzling automagic way because:
... although I understand the appeal of generic solution using method swizzling.
We do make one exception to that in case of observing rx_deallocating method calls.
I didn't see any other way to support rx_observeWeakly without doing this.
That small amount of swizzling can even be turned off using DISABLE_SWIZZLING definition :)
However, there is a space for third party RxSwift-compatible pods that adds this feature, so if you’re up for making it I’m sure there’d be an audience for it.
[A.] Orta Therox
w/ Artsy http://artsy.net/CocoaPods http://cocoapods.org/ / CocoaDocs http://cocoadocs.org/ / GIFs.app https://itunes.apple.com/us/app/gifs/id961850017?l=en&mt=12
@orta http://twitter.com/orta / orta.github.com http://orta.github.com/
Artsy is totally hiring iOS Devs https://artsy.net/job/mobile-engineer ATMOn 7 Oct 2015, at 21:49, Krunoslav Zaher [email protected] wrote:
Hi @sergdort https://github.com/sergdort ,
We don't officially support out of the box observing of method calls :)
People usually have some kind of base classes for their projects, so in that base class you just expose PublishSubject called onPrepareForReuse (or something like that), override onPrepareForReuse and call .on(.Next()).
So far I see that as a preferred way over swizzling automagic way because:
there can't be any collisions with KVO or some third party framework that does that swizzles for some reason (although I wouldn't suggest include those kinds of frameworks anyway)
the moment at which that event is dispatched is clear with respect to class hierarchy
people usually have just a couple of base classes per project so the effort to do this per project is really tiny IMHO... although I understand the appeal of generic solution using method swizzling.
We do make one exception to that in case of observing rx_deallocating method calls.
I didn't see any other way to support rx_observeWeakly without doing this.That small amount of swizzling can even be turned off using DISABLE_SWIZZLING definition :)
—
Reply to this email directly or view it on GitHub https://github.com/ReactiveX/RxSwift/issues/181#issuecomment-146308770.
Yeah, I'm assuming there will be some third party compatible pods or something since people will probably want this feature :)
Thanks, @kzaher @orta
Did you mean something like this ?
import UIKit
import RxSwift
class RxTableViewCell: UITableViewCell {
let onPrepareForReuse:Observable<Void> = PublishSubject()
override func prepareForReuse() {
super.prepareForReuse()
(self.onPrepareForReuse as? PublishSubject<Void>)?.on(.Next())
}
}
@sergdort ,
yep, that's what we would functionally simulate if we would support this out of the box by using swizzling :)
@kzaher Thanks :)
Sorry to bring up an old thread, just wondering if you think something like rx_prepareForReuse might be something worth considering in RxCocoa, or should that be kept in a separate library? I'm having this issue now and can devote some time to making a swizzling-based solution – just need to know where to put it.
Hi @ashfurrow ,
I would ideally want to not do swizzling in this project, but it looks like people expect this project to have some nice features and it looks like swizzling is the only way to do them ....
I think this is more of a question would we support generic rx_observeInvocationForSelector that we could use to implement rx_prepareForReuse, rx_viewWillAppear, rx_viewDidAppear ...
I'm kind of internally generally against shipping swizzling code because it does adds some uncertainty, but on the other hand, I can't ignore people wanting this feature of the box, or say that I can't understand why they want it.
I think it would make sense to try to do a prototype for a generic rx_observeInvocationForSelector and see how complex would the implementation be. If we can find an implementation that is simple enough and doesn't represent much risk, and we mark it with
#if !DISABLE_SWIZZLING
... I think we could include it in this library.
That code will probably get more attention here, then in some separate library, so more eyes on it the better.
If we decide that implementation is too big and out of scope of this project to maintain, then we can pull that code in some external repository.
Hope this makes sense :)
OK, cool, that all sounds 👌 Would you like to open an issue to discuss implementation details?
If you can try to play around and see how complex would it be to extend our current code to support observing of void method calls, that would be great :)
I think that we would like to support something like func rx_observeInvocationForSelector(selector: SEL) -> Observable<[NSArray]> for void methods, and assert when trying to observe methods that have return value.
I think that should be pretty similar to what we currently have to swizzle dealloc method :)
If you can make some prototype for us to have better understanding, that would be :+1:
Does that functionality seem reasonable to you and would it be sufficient to satisfy your issue? :)
Will do!
I spent some time this afternoon trying to work on this, it's not an easy problem. I'm just going to use the PublishSubject-in-subclass approach for now and hopefully will have time to revisit this soon.
Hi @ashfurrow ,
I think we can conceptually use associated PublishSubjects<[AnyObject]>.
If I remember from last time when I was investigating this, this is where I've documented issues related with swizzling.
I think the correct approach is * by swizzling xxxx method on all instances for a class.
KVO creates dynamic subclasses internally, so that's quite a mess :) For that reason I wouldn't suggest creating dynamic subclasses and changing class dynamically.
The way we swizzled dealloc method is here.
Getting a full solution running shouldn't be significantly more tricky. Probably the most complex part is parsing selector arguments and generating intercept block on the fly.
I can help investigate next weekend :)
If you want swizzling done right while retaining the possibility of plugging it in RxSwift, I highly recommend Peter Steinberger's Aspects:
https://github.com/steipete/Aspects
I use it in production code and it's very nice.
Yeah I've used it before, great library. Though it has some limitations that make it difficult to use for general-purpose stuff like this.
Aspects is, as the name says, a library to write implementations using the Aspect Oriented Programming paradigm, so I would say that is too big to be included in a project with no external dependencies and that aims to stay as much indie as possible like this one. :)
I'm not suggesting to include Aspects in RxSwift, simply that it's a pretty good solution for add-ons. I use Aspects in production as a helper in MVVM infrastructure code (to inject the model in a protocol-conforming view controller during a segue) and it's been working pretty well -- although that's out of laziness and I'll move to a more formal model.
This said, the "too big" argument itself wouldn't justify ruling it out, given the sheer code size of RxSwift already :)
I'm thinking something small .... smaller then a library ... :)
It's good to have reference though. Looks like everybody likes to swizzle forwardInvocation and _objc_msgForward ...
I have a plan in my head ... I need to test it :)
This should be release now.
rx_sentMessage
Finally closing this :)
Let me know if there are any issues.