2

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

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

@private
    MyMarker MyClass instance;
4

2 回答 2

5

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

#define IBOutlet
#define IBAction void

完全不影响编译。Interface Builder 直接读取你的头文件(当头文件更改时它会由 Xcode 通知,但它只是读取和解析头文件本身。

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

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

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

于 2009-07-29T07:23:05.903 回答
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)来保存您想要的附加信息。

于 2009-07-29T19:15:04.780 回答