luvieere
luvieere

Reputation: 37494

Aspect-Oriented Objective-C Library?

Is there any Aspect-Oriented Objective-C library that I could perhaps use for iPhone development?

Upvotes: 23

Views: 5489

Answers (11)

Assuner
Assuner

Reputation: 1

https://github.com/eleme/Stinger

Stinger is a high-efficiency library with great compatibility, for aop in Objective-C, using libffi.

Upvotes: 0

Tiago
Tiago

Reputation: 934

The question is old but I discovered this project today and it might be helpful to someone in the future.

https://github.com/steipete/Aspects

Upvotes: 4

Amin Negm-Awad
Amin Negm-Awad

Reputation: 16660

I'm working on a real (it is more than method-swizzling) AOP-Framework for Objective-C. An alpha will be released soon. You can listen to my german presentation on the Macoun'09 conference here: http://www.macoun.de/video2009ts6.php

If you're still interested in AOP for Objective-C you can send me a mail to [email protected] or simply visit this site: aspective-c.com/index.html in a few weeks. There will be an english version (yup, not translated by me ;-)) of the site and the manual in a few weeks.

Upvotes: 0

I made some rudimentary aop pre and post process function on an NSObject category

@implementation NSObject (AOP)

- (void)preprocess:(SEL)sel with:(void (^)(id obj, id param))implementingBlock{
    Method m1 = class_getInstanceMethod(self.class, sel);
    IMP imp1 = method_getImplementation(m1);

    SEL replacement = sel_registerName( [[[NSString stringWithUTF8String:sel_getName(sel)] stringByAppendingString:@"pre"] cStringUsingEncoding:NSUTF8StringEncoding]);
    class_addMethod(self.class,replacement, imp1, nil);

    method_setImplementation(m1, imp_implementationWithBlock(^(id x, id param){
        implementingBlock(x,param);
        [x performSelector:replacement withObject:param];
    }));
}

- (void)postprocess:(SEL)sel with:(void (^)(id obj, id param))implementingBlock{
    Method m1 = class_getInstanceMethod(self.class, sel);
    IMP imp1 = method_getImplementation(m1);

    SEL replacement = sel_registerName( [[[NSString stringWithUTF8String:sel_getName(sel)] stringByAppendingString:@"post"] cStringUsingEncoding:NSUTF8StringEncoding]);
    class_addMethod(self.class,replacement, imp1, nil);

    method_setImplementation(m1, imp_implementationWithBlock(^(id x, id param){
        [x performSelector:replacement withObject:param];
        implementingBlock(x,param);
    }));
}
@end

Upvotes: 0

Pascal
Pascal

Reputation: 11

Check out this one https://github.com/pvantrepote/FlexOC It's an alpha version and uses (for now) the Proxy implementation. It does also dependency injections.

Upvotes: 1

Andras
Andras

Reputation: 376

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. In methodSignatureForSelector: we gave back the correct message signature that is already stored in a dictionary in a method wrapper object.

  7. 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].

  8. 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.

Upvotes: 6

MacMark
MacMark

Reputation: 6549

With Objective-C i would suggest to go with the here much used Category- and Delegate-Pattern. These can be more useful than AOP. Don't try and solve your problems with solutions you learned for other languages.

Upvotes: 0

Dave DeLong
Dave DeLong

Reputation: 243156

Another one is Aspect Objective-C: https://github.com/tomdalling/AspectObjectiveC

Upvotes: 0

fsix
fsix

Reputation: 11

All still interested people should take a look at https://github.com/mgebele/MGAOP

This seems to be a new project with future potential.

Upvotes: 1

Moszi
Moszi

Reputation: 3236

Also you might want to check out the library at https://github.com/moszi/AOP-in-Objective-C which is a very simple NSProxy subclass allowing you to intercept the beginning and the end of the method calls.

With this you can even create a proxy class for you objects to make sure messages sent to your object are serialized over one single thread, regardless of the invoking thread.

Upvotes: 2

PeyloW
PeyloW

Reputation: 36752

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.

Upvotes: 8

Related Questions