【问题标题】:IBOutlet like constructs in the Objective-C runtimeObjective-C 运行时中的类似 IBOutlet 的构造
【发布时间】:2009-07-29 06:37:51
【问题描述】:

我对 IBOutlets 的理解是它们充当了 Objective-C 类中 ivars 和属性的标记。 Objective-C 运行时中是否有任何东西可以让人们在运行时查询 ivar 或属性或类是否已用 IBOutlet 标记?还是 XCode 只是在编译时对这些做了一些巧妙的处理?

如果它们是运行时构造,是否可以定义自己的标记并以这种方式使用它们:

@private
    MyMarker MyClass instance;

【问题讨论】:

    标签: objective-c objective-c-runtime


    【解决方案1】:

    据我了解,Interface Builder 只是读取头文件。 IBOutlet 和 IBAction 是微不足道的#defines:

    #define IBOutlet
    #define IBAction void
    

    完全不影响编译。 Interface Builder直接读取你的头文件(当头文件发生变化时是notified by Xcode,但它只是读取和解析头文件本身。

    当 nib 文件被取消归档时,值是通过普通接口使用 ivar 或属性设置的,但没有什么特别注意 ivar/property 可由 Interface Builder 使用。

    所以不,IBOutlet/IBAction 属性的存在没有存储,无法访问,也不能添加自己的属性。

    您可以查看属性,看看是否有任何有用的东西可以通过属性附加到 ivar,但我会感到非常惊讶。

    【讨论】:

      【解决方案2】:

      是的,IBOutlet 和 IBAction 只是在预编译阶段被解析器丢弃,所以编译后的输出中没有任何内容。如上所述,它们只是由 Interface Builder 进行文本处理,因此它知道哪些属性/方法子集可用于连接窗口。

      但是,这并不能阻止您自己做同样的事情——您可以只定义一些由预处理器编译出来的#define,并使用文本处理来操作它们。但是这些在运行时都不可用,这意味着你不能真正按照你的建议去做。

      在技术上可以编写一个宏来对属性/ivar 进行一些操作,然后将额外信息添加到不同的 ivar;例如:

      #define OUTLET(type,name) type name;BOOL property_##name;
      @interface Foo : NSObject
      {
              OUTLET(NSString*,foo);
      }
      @end
      

      将扩展为

      @interface Foo :NSObject
      {
          NSString* foo;
          BOOL property_foo;
      }
      @end
      

      然后您可以使用 property_foo 的存在来处理您的代码(在运行时和编译时应该可以检测到)。

      我一般不建议尝试这样做...首先,它会使您的界面(以及因此的内存对象)比它们需要的更大。您最好创建自己的类(或结构 typedef)来保存您想要的附加信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-06
        • 1970-01-01
        • 1970-01-01
        • 2011-06-05
        • 1970-01-01
        • 2014-08-15
        • 2014-07-26
        相关资源
        最近更新 更多