【问题标题】:Why are there private instance variables in Cocoa headers?为什么 Cocoa 标头中有私有实例变量?
【发布时间】:2014-06-25 10:38:09
【问题描述】:

在 Foundation、UIKit 和其他框架头文件中有多个 @private 实例变量示例。以下是一些示例:

//CLLocationManager.h
@interface CLLocationManager : NSObject
{
@private
    id _internal;
}
<...>

//NSAutoreleasePool.h
@interface NSAutoreleasePool : NSObject {
@private
    void    *_token;
    void    *_reserved3;
    void    *_reserved2;
    void    *_reserved;
}
<...>

等等

这些实例变量是@private,因此除了类本身之外,无法从任何地方访问它们。在标题中公开它们有什么意义?

为什么不呢

//CLLocationManager.m
@interface CLLocationManager<>
{
    id _internal;
}

甚至,考虑到现代的 Objective-C 语法:

//CLLocationManager.m
@interface CLLocationManager<>

@property(nonatomic, assign) id internal;

为什么苹果在头文件中使用私有实例变量,暴露类的内部而不是隐藏在实现中?

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    Apple 多年来对 API(应用程序接口)所做的更改,但从结构和类中删除成员会更改 ABI(应用程序二进制接口),如果不强制重新编译所有现有程序,否则它们无法完成。会崩溃。

    void *_reserved 成员实际上很可能是已从 API 中删除的旧的弃用符号,但从类定义中删除它们会更改 ABI,因此它们占用的空间已被填充void *.

    【讨论】:

    • 您对 ABI 的使用并不特别正确,它们都是您使用的 API……现在有了更灵活的 ABI,API 更加灵活……
    【解决方案2】:

    这些头文件中有许多是在古代创建的,当时实例变量必须在头文件中声明。除非有充分的理由,否则您不想更改工作代码 - 毕竟,一切正常,您只是好奇。

    Apple 不能只更新头文件;他们还必须更新实现,这意味着大量测试(或者你认为你可以在几十个文件中进行更改而不会出错?)

    【讨论】:

    • Apple 更改工作代码。如果您为 iOS/Mac 开发了足够长的时间,您会注意到多种方法正在被弃用,新属性被引入等等。例如,在最近的 NSArray.h 测试版中,- (NSUInteger)count; 被替换为@property (readonly) NSUInteger count;
    猜你喜欢
    • 2012-02-08
    • 2011-11-29
    • 2011-05-13
    • 2011-01-23
    • 2012-04-10
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多