【问题标题】:Use Class Extension for Selective Visibility in Objective-C在 Objective-C 中使用类扩展来实现选择性可见性
【发布时间】:2011-10-29 22:41:25
【问题描述】:

有选择地将类扩展放在它们自己的.h 文件和#import 中以获得类的方法和属性的不同级别的可见性是否有意义?如果这是一个坏主意(或行不通),为什么?

【问题讨论】:

    标签: objective-c class-extensions


    【解决方案1】:

    Objective-C 中的类扩展(与子类相反)是通过类别完成的。在 Xcode 中,转到文件 > 新建 > 文件并选择 Objective-C 类别。它将询问您如何调用该类别以及它应该扩展什么类。您将获得一个 .h/.m 对,分别用于放置您的接口和实现。如果您想访问扩展程序中提供的功能,只需导入其 .h 文件即可。

    【讨论】:

    • Categories and Extensions 类似,但又不相同。 “类扩展类似于匿名类别,只是它们声明的方法必须在对应类的主 @implementation 块中实现。”
    • @albertamg,理论上,如果.m不导入包含类扩展的.h,那么它就不必实现它,对吧?
    • @Yar 好吧,如果没有将类扩展名导入到 .m 文件中,编译器不会抱怨实现不完整。
    • 投反对票是我的;类扩展不是类别,反之亦然。它们是完全不同的东西(例如,扩展不能有实现,类别不能影响属性合成)。而且,是的,如果未导入扩展,编译器将不知道需要实现(类别的行为也不同;类别根本不必具有相应的 @implementation)。
    【解决方案2】:

    这是一个好主意,也正是设计类扩展的原因(以及它们与类别不同的​​原因)。

    也就是说,您可以:

    Foo.h

    @interface Foo:NSObject
    ...public API here...
    @property(readonly, copy) NSString *name;
    @end
    

    Foo_FrameworkOnly.h

    @interface Foo()
    @property(readwrite, copy) NSString *name;
    @end
    

    Foo.m

    #import "Foo.h"
    #import "Foo_FrameworkOnly.h"
    
    @interface Foo()
    ... truly implementation private gunk, including properties go here ...
    @end
    
    @implementation Foo
    @synthesize name = name_;
    @end
    

    并且有效地拥有一个公共只读和私有读写的属性,仅用于导入 Foo_FrameworkOnly.h 的实现文件。

    【讨论】:

    • 谢谢@bbum,那太好了……您的示例为您提供了公共、包(或其他)和私有的,这几乎是我所希望的。就个人而言,我认为在文件级别这样做是非常可怕的,但我猜这就是接近金属的代价。
    • 在文件级别以外支持私有 API 会带来巨大的复杂性,特别是在像 Objective-C 这样的纯动态语言中,无论如何“私有”实际上是没有意义的(即编译器无法编译掉或完全混淆“私有”符号)。
    • (我并不反对——只是说成本很高)你可能也会觉得这很有趣:stackoverflow.com/questions/2158660/…
    • 您的意思是运行时(可能还有编译器)的巨大复杂性。感谢您的链接,它确实有助于充实讨论。
    • 是的;运行时和编译器,绝对是。
    猜你喜欢
    • 2013-06-16
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 2011-11-07
    • 2020-12-05
    相关资源
    最近更新 更多