Use trampolines to allow hooking methods multiple times per class hierarchy.
WIP: This still misses the assembly trampoline code for x86_64 (iOS Simulator 64 bit)
This fixes #2, #11 and is an alternative take on #13. (actually my second one, after I gave up on the alloc swizzling approach.)
I don't like the fact that this requires custom assembly, but once you understand what happens here, it's really not all that scary and easily portable to new platforms. Apple basically does the same internally with their imp_implementationWithBlock() method. We're also somewhat architecture dependent already with the struct return detection and C calling conventions, although that bit was doable in C with platform ifdefs.
The trampolines allow us to rename each hooked method, which then allows us to identify what IMP is actually called here, solving the super-problem when dealing with NSInvocation.
Also pinging @OliverLetterer: Is the shout-out in the readme under Credits enough? Or should I add your name to the MIT license as well?
There's a lot of potential here, since this is the proper fix for the subclassing problem and a starting point to explore more wide usage, like using point-cut expression language (#10).
Amazing! I'll close #13.
Since aspects_implementationForwardingToSelector is pretty much the same as imp_implementationForwardingToSelector, I would suggest we expose only that function in a new CocoaPod named forwarding-implementation. Thanks to CocoaPods, we can easily add that as a dependency to both Aspect and SPLMessageLogger and we would win a shared codebase which is easier maintainable and expandable (wrt the missing x86_64 implementation for example).
Sounds good!
I finally found some time to move imp_implementationForwardingToSelector into its own podspec and added it as a dependency to my own project.
CocoaPods pull request is waiting here.
Looking good. I'm thinking about making this an optional dependency, since it's not required for per-object-hooking.
Any update on this?
Still misses the arm64 assembly :/
I needed to do this for aspects_forwarding_trampoline_[stret_]armv7.s to compile (produce symbols, actually):
-#ifdef _ARM_ARCH_7
+#if defined(__arm__) && !defined(__arm64__)
@andrebraga and was that enough for getting Aspect working on arm64? or did you do something else? it is still failing here
To be honest I have disabled the arm64 targets on my project because I’m using a couple of closed source, binary-only frameworks that are still stuck on 32 bits. My diff only made things compile for armv7, and for the time being that’s good enough. I was only tipping @steipete that his define might not be general enough since _ARM_ARCH_7 wasn’t defined for my project, at least not by the time the assembly files were built.
On Jun 6, 2014, at 3:18, dcordero [email protected] wrote:
@andrebraga and was that enough for getting Aspect working on arm64? or did you do something else? it is still failing here
— Reply to this email directly or view it on GitHub.
poke, still wanting this for ARAnalytics
FWIW, this works well enough for me: https://github.com/dcordero/AOP-for-Objective-C
For my use I could replace Aspects with no loss. Maybe the technique in there could be made to work.
Any update regarding the arm64 support?
Not yet; I keep using the previous version without assembler craziness (and only for testing). But If you wanna spend some time to help - I'm all for it.
Any update guys for 64 bit support?
My work around is that I will hook into the the parent's class (ie: UIViewController). In the callback block, I will check [[aspectInfo instance] class] to see if they are among the classes I want to hook into and act accordingly.
I am wondering what the performance overhead is of hooking into every single subclass of the parent's class.