Aspect-Oriented Objective-C Library?
Check out my article about a possible solution: http://codeshaker.blogspot.com/2012/01/aop-delivered.html
The base idea is to make a hook into the message sending mechanism and force it to the message forwarding route:
So A brief explanation about how it works:
At registration of a method call of a specific class it creates a method wrapper (AOPMethod) object and stores every information in it about that specific method along with the block that will be used upon interception.
Changes the implementation of the method to _objc_msgForward or _objc_msgForward_stret respectively using method_setImplementation. This is the point where we route message sending to the forwarding mechanism. The next time the message is called on the base class, it will return the _objc_msgForward implementation as if it not found the implementation. So it starts to resolve it by going through the message forwarding steps. Nice.
We add the forwardingTargetForSelector: method to the base class using class_addMethod to point to our implementation in the AOPAspect class. Also we add the original method implementation and selector (with an extended name to prevent conflicts between classes) to our AOPAspect instance.
In the forwardingTargetForSelector: method we give back our AOPAspect instance. With this we route the message forwarding from the base object to our AOPAspect object.
This forwardingTargetForSelector: method will be called again on AOPAspect as we don't have that selector implemented. This case we return nil, so message forwarding steps further and will check for the methodSignatureForSelector: and forwardInvocation: methods on AOPAspect.
In methodSignatureForSelector: we gave back the correct message signature that is already stored in a dictionary in a method wrapper object.
At the time it arrives to our implementation of forwardInvocation: in AOPAspect we have a fully configured NSInvocation instance and the only thing we have to do is to change the selector to the extended version we added to AOPAspect class. Here we can run the blocks registered for the given method before/after or even instead of the method call. And of course we can run the original method by calling [anInvocation invoke].
For simplicity, we just pass the NSInvocation object to the blocks registered for the method, so they can access all arguments and the return value as well through the getArgument:atIndex: and getReturnValue: methods.
And that's it. It works with all kind of return types, argument types and any variation of arguments.
You can find the concrete example on the above link. Please feel free to use it.
There is an old project called AspectCocoa, this might be what you are searching for.
Otherwise Í would suggest rolling your own. Either proxy based AOP by subclassing NSProxy
for a change. Or you could do some method swizzling with the quite cool Obj-C run-time function method_exchangeImplementations()
.
But unless you are looking for a fun exercise, ask yourself what you want to achieve, and if there is an existing perfectly working Objective-C way to do it.