7

我觉得现代 Objective-C 鼓励使用实例变量作为内存管理和键值观察的属性。这很好用,我在实现文件中使用接口作为私有变量,如下所示:

@interface MyClass ()
@property NSObject* myVar;
@end

但是,如何制作受保护的变量?在上述情况下,我的子类将无法看到这样声明的属性。我可以走 iVar 路线,但是如果像上面那样声明私有变量并且受保护的是 iVar,那么其余代码就会感觉不对劲。

我已经阅读了这个解决方案:Workaround to complete protected properties in Objective-C,但它似乎使代码过于复杂。

4

1 回答 1

14

您最好的选择是在第二个头文件中使用一个类别,例如 MyClass_protected.h,并将其包含在主类和子类中,如您链接的解决方案中所建议的那样。这真的很简单,根本没有“过于复杂”,只是一个额外的文件。

Objective-C 具有很强的自省特性。无论您如何或在何处声明属性(或任何其他函数,就此而言),您都可以从任何地方访问它。除非您正在编写的代码可以看到相应的声明或实现,否则您将收到编译器警告(除非您使用类似performSelector...家族之一的内省方法)。接口的唯一原因是名称安全、类型安全和防止编译器警告。因此,您有几个选择:

主类接口

您将获得实现安全(即,如果您不实现方法,编译器将发出警告)。但是,每个类(导入你的)都会看到这些方法。您可以使用注释来指示该方法应该受到保护,但当然除非他们检查源,否则没有人会看到它。当我是项目中唯一的程序员时,我最常使用它,因为我知道应该保护什么,不应该保护什么。

同一 .h 文件中的类别

如上所述,除非他们检查源代码,否则程序员不会看到它受到保护,但如果他们这样做会更加明显。如果您在命名类别 ( @interface MyClass (protected)) 中声明它,您将失去类型安全性,但您的意图更加明确。我最常使用它来模拟抽象方法 - 即明确地不是实现安全的,但应该对每个人都可见。

子类的 .m 文件中的一个类别直接

这是个坏主意,不要这样做。您确实只看到子类中的方法,但是您失去了实现安全性,并且真的感觉不对。我只将它用于单元测试,最终将它们迁移到单独的标题中。

单独标头中的类别 (MyClass_protected.h)

首选的解决方案和最接近的 Objective-C 可以访问受保护的方法。这只是一个文件,说真的,不要把你的内裤弄成一堆。您可以使用类扩展(它们是匿名类别)并且不会失去实现安全性。它只对包含它的类可见,应该只是子类;由于标头名称,包含的方法旨在用作受保护的事实应该对所有人来说都是显而易见的,除了最不称职的程序员。

于 2013-08-03T01:45:42.587 回答