IBOutlet类似于Objective-C运行时中的构造

时间:2009-07-29 06:37:52

标签: objective-c objective-c-runtime

我对IBOutlets的理解是它们作为Objective-C类中ivars和属性的标记。 Objective-C运行时中是否有任何内容可以让人们在运行时查询ivar或属性或类是否已用IBOutlet标记?或者XCode在编译时只是做了些巧妙的事情?

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

@private
    MyMarker MyClass instance;

2 个答案:

答案 0 :(得分:4)

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

#define IBOutlet
#define IBAction void

根本不影响编译。 Interface Builder直接读取您的头文件(当头文件发生更改时它是notified by Xcode,但它只是读取并解析头文件本身。

当nib文件被解除归档时,通过普通接口使用ivar或属性设置值,但没有注意到Interface Builder可以使用ivar / property。

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

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

答案 1 :(得分: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的存在来对您的代码执行某些操作(在运行时和编译时都应该可以检测到这些内容)。

我不建议尝试这样做但是...一开始,它会使你的界面(以及因此内存对象)比他们需要的更大。你最好创建自己的类(或struct typedef)来保存你想要的其他信息。