简体   繁体   English

面向方面的Objective-C库?

[英]Aspect-Oriented Objective-C Library?

有没有可能用于iPhone开发的面向方面的Objective-C库?

There is an old project called AspectCocoa , this might be what you are searching for. 有一个名为AspectCocoa的旧项目,这可能是您要搜索的项目。

Otherwise Í would suggest rolling your own. 否则,Í会建议您自己滚动。 Either proxy based AOP by subclassing NSProxy for a change. 通过将NSProxy子类NSProxy更改,可以使用基于代理的AOP。 Or you could do some method swizzling with the quite cool Obj-C run-time function method_exchangeImplementations() . 或者,您可以使用非常酷的Obj-C运行时函数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. 但是除非您正在寻找有趣的练习,否则请问自己自己想要达到的目标,以及是否存在可以完美实现的Objective-C方法。

Check out my article about a possible solution: http://codeshaker.blogspot.com/2012/01/aop-delivered.html 查看我有关可能解决方案的文章: 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. 在注册特定类的方法调用时,它会创建一个方法包装器(AOPMethod)对象,并将有关该特定方法的所有信息以及将在拦截时使用的块存储在其中。

  2. Changes the implementation of the method to _objc_msgForward or _objc_msgForward_stret respectively using method_setImplementation. 使用method_setImplementation将方法的实现分别更改为_objc_msgForward或_objc_msgForward_stret。 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. 下次在基类上调用该消息时,它将返回_objc_msgForward实现,就好像找不到该实现一样。 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. 我们使用class_addMethod向基类中添加forwardingTargetForSelector:方法,以指向AOPAspect类中的实现。 Also we add the original method implementation and selector (with an extended name to prevent conflicts between classes) to our AOPAspect instance. 此外,我们还将原始方法实现和选择器(具有扩展名,以防止类之间发生冲突)添加到AOPAspect实例中。

  4. In the forwardingTargetForSelector: method we give back our AOPAspect instance. 在ForwardingTargetForSelector:方法中,我们返回AOPAspect实例。 With this we route the message forwarding from the base object to our AOPAspect object. 这样,我们就将消息转发从基础对象路由到我们的AOPAspect对象。

  5. This forwardingTargetForSelector: method will be called again on AOPAspect as we don't have that selector implemented. 由于我们尚未实现该选择器,因此将在AOPAspect上再次调用该forwardingTargetForSelector:方法。 This case we return nil, so message forwarding steps further and will check for the methodSignatureForSelector: and forwardInvocation: methods on AOPAspect. 在这种情况下,我们返回nil,因此消息转发进一步进行,并将检查AOPAspect上的methodSignatureForSelector:和forwardInvocation:方法。

  6. In methodSignatureForSelector: we gave back the correct message signature that is already stored in a dictionary in a method wrapper object. 在methodSignatureForSelector中:我们返回了正确的消息签名,该签名已经存储在方法包装对象的字典中。

  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. 当它到达我们实现forwardInvocation的时候:在AOPAspect中,我们有一个完全配置的NSInvocation实例,我们唯一要做的就是将选择器更改为添加到AOPAspect类的扩展版本。 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]. 当然,我们可以通过调用[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. 为简单起见,我们仅将NSInvocation对象传递给为该方法注册的块,因此它们也可以通过getArgument:atIndex:和getReturnValue:方法访问所有参数和返回值。

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. 请随时使用它。

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 https://github.com/steipete/方面

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. 另外,您可能想在https://github.com/moszi/AOP-in-Objective-C中检出该库,这是一个非常简单的NSProxy子类,允许您截获方法调用的开始和结束。

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. 这样,您甚至可以为对象创建一个代理类,以确保发送到对象的消息在单个线程上被序列化,而与调用线程无关。

Check out this one https://github.com/pvantrepote/FlexOC It's an alpha version and uses (for now) the Proxy implementation. 看看这个https://github.com/pvantrepote/FlexOC这是一个alpha版本,目前使用Proxy实现。 It does also dependency injections. 它也确实依赖注入。

All still interested people should take a look at https://github.com/mgebele/MGAOP 所有仍然有兴趣的人应该看看https://github.com/mgebele/MGAOP

This seems to be a new project with future potential. 这似乎是一个具有未来潜力的新项目。

I made some rudimentary aop pre and post process function on an NSObject category 我在NSObject类别上做了一些基本的aop前后处理功能

@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

I'm working on a real (it is more than method-swizzling) AOP-Framework for Objective-C. 我正在为Objective-C开发一个真正的AOP框架(不仅仅是方法麻烦)。 An alpha will be released soon. 即将发布Alpha版。 You can listen to my german presentation on the Macoun'09 conference here: http://www.macoun.de/video2009ts6.php 您可以在以下Macoun'09会议上收听我的德语演讲: http : //www.macoun.de/video2009ts6.php

If you're still interested in AOP for Objective-C you can send me a mail to negm-awad@cocoading.de or simply visit this site: aspective-c.com/index.html in a few weeks. 如果您仍然对Objective-C的AOP感兴趣,可以给我发邮件到negm-awad@cocoading.de或在几个星期内直接访问以下站点: aspective-c.com/index.html There will be an english version (yup, not translated by me ;-)) of the site and the manual in a few weeks. 该网站和手册将在几周内提供英文版(是的,我自己未翻译;-))。

https://github.com/eleme/Stinger https://github.com/eleme/Stinger

Stinger is a high-efficiency library with great compatibility, for aop in Objective-C, using libffi. Stinger是一个高效库,具有高度的兼容性,对于使用libffi的Objective-C中的aop而言。

另一个是Aspect Objective-C: https//github.com/tomdalling/AspectObjectiveC

With Objective-C i would suggest to go with the here much used Category- and Delegate-Pattern. 对于Objective-C,我建议使用这里经常使用的“类别”和“代表模式”。 These can be more useful than AOP. 这些可能比AOP有用。 Don't try and solve your problems with solutions you learned for other languages. 不要尝试使用从其他语言中学到的解决方案来解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM