Objective-C 在64位机器上, 类的访问控制和每一个类以及实例变量的访问控制都有一个与之关联的标识. 所有使用这个类和实例变量的对象都会引用这个标识. 这些标识服从于连接器的访问控制规则.
这样的结果就是访问一个私有类或者成员变量会有更严格的限制. 非法使用一个私有的成员变量会得到连接错误的结果.提供类和成员变量的Frameworks必须正确的导出它们的标识. 在特殊情况下, frameworks是用fvisibility=hidden
构建的 或者 是使用连接器导出一个可能需要被改变的成员变量列表 构建的.
类标识名字的格式是:_OBJC_CLASS_$_ClassName
和_OBJC_METACLASS_$_ClassName
. 类标识是给发送消息给这个类的对象使用的(也就是[ClassName someMessage]
). metaclass的标识是给这个类的子类使用的. 他们是通过gcc的可见标志标识起作用的, 因此-fvisibility=hidden
将会导致这个类的标识 non-exported
. 在连接器导出列表以及在将它翻译到这些列表中的时候连接器认识老的标识名.objc_class_name_ClassName
.
在默认情况下类标志是exported
.
单个类的可见性可以通过一个attribute
改变:
__attribute__((visibility("hidden")))
@interface ClassName : SomeSuperclass
拥有默认可见性的类, 这个类的标识是exported
, 而成员变量的标识是按照后面的描述处理的. 拥有hidden
可见性的类, 这个类的标识以及成员变量的标识都是not exported
.
成员变量标识的格式是:_OBJC_IVAR_$_ClassName.IvarName
. 成员变量的标识是给那些读或者写这个成员变量的对象用的.
在默认情况下, 成员变量的标识是@private
和@package
成员变量是不exported
的, 而@public
和 @protected
标识的成员变量是exported
. 这可以通过导出列表改变, -fvisibility
, 或者通过这个类的可见性属性改变. 在单独的成员变量上还不支持可见性属性.
网友评论