是什么决定了未实现方法的解决过程?

时间:2011-01-29 05:12:53

标签: objective-c cocoa objective-c-runtime

据我了解,未实现的方法可通过以下方式解决:

  1. resolveInstanceMethod:/ resolveClassMethod:有机会实现方法
  2. forwardingTargetForSelector:有机会转发给委托
  3. forwardInvocation:有机会按照自己认为合适的方式处理该方法。
  4. 这个三步流程定义在哪里?我想自己处理它,因为NSInvocation可能对我的需求来说太重了。我已经在运行时源周围捅了一下,看不到任何东西。

    看起来旧的运行时会向前调用:args:在接收器上执行此操作但似乎已经从新的运行时调用。我猜这个过程必须由框架而不是运行时定义,因为如果运行时依赖于Cocoa到需要NSInvocation来处理消息的程度,那就太奇怪了。它可能是一个未记录的方法,可以在NSObject / NSProxy上调用吗?

    修改

    看起来运行时声明,但从未定义,当objc_msgSend找不到实现时调用的C函数:

    id objc_msgForward(id object,SEL message,...);

    我不为Apple工作,所以我不知道Foundation如何实现这一点,但至少在Cocotron的情况下,他们使用:

    id objc_msgForward(id object,SEL message,...)
    {
       Class       class=object->isa;
       struct objc_method *method;
       void       *arguments=&object;
    
       if((method=class_getInstanceMethod(class,@selector(forwardSelector:arguments:)))!=NULL)
            return method->method_imp(object,@selector(forwardSelector:arguments:),message,arguments);
       else
       {
           OBJCRaiseException("OBJCDoesNotRecognizeSelector","%c[%s %s(%d)]", class_isMetaClass(class) ? '+' : '-', class->name,sel_getName(message),message);
           return nil;
       }
    }
    

    添加forwardSelector:arguments:方法似乎不起作用,所以我猜这是特定于Cocotron的。有人知道objc_msgForward在基金会做了什么吗?

1 个答案:

答案 0 :(得分:6)

  

我写的东西有点像   使用消息的脚本语言   转发到接口   Objective-C的。现在,我正在使用   NSInvocation,但最终可能会结束   每次这样做数千次   第二,所以开销就是   显。但我想我也是   好奇...

就消息转发而言,不同平台和运行时版本的行为[通常略有不同]。

无论如何,不​​要重新发明轮子。今天有两种语言桥可以完全接近全保真桥接,您可以从中学到很多东西。两者都有自由许可,专门允许这种重复使用。

具体来说,MacRuby项目提供了一个Ruby实现,它位于CoreFoundation和Objective-C垃圾收集器之上。它是“最本土”的桥梁(并且因此不是非常便携 - 不是项目的目标)。

PyObjC桥是Objective-C运行时和另一个动态OO语言运行时之间高保真桥的最佳示例;蟒蛇。虽然非Mac OS X位可能有点腐烂,但它更便携一些。

(我不会提及F-Script;一种基于Objective-C构建的新语言,我相信,源代码是可用的?)

所有桥接都涉及方法转发,子类化和跨运行时代理,所有这些都听起来适用于您的特定需求。