以下使用objc @protected指令安全/合法吗?

时间:2017-03-18 21:53:00

标签: objective-c properties protected

我必须将私有属性暴露给子类。 由于没有"受保护的属性"在objc AFAIK中,我使用@protected指令来暴露由编译器合成的相应的ivar。

这种方法似乎有效,但是,我不确定我是否会以某种不可取的方式影响属性和ARC的合成?

我在这里使用弱属性来显示编译器如何强制我使用带有@protected指令的__weak修饰符,即看起来编译器知道这两个声明及它们之间的链接。

超类.h文件

@interface Superclass : NSObject
{
@protected
SCNScene * __weak _scnScene;
}

@end

超类.m文件

@interface Superclass ()
@property (weak, nonatomic) SCNScene * scnScene;
@end

@implementation Superclass
........
@end

子类.m文件

@implementation Subclass
    // Can use _scnScene just fine
    _scnScene = .....
@end

2 个答案:

答案 0 :(得分:0)

在类声明的上下文中,else是实例变量的默认可见性,因此您的声明无效。实际上,以下声明:

protected

与您发布的声明具有完全相同的效果,因为编译器会自动为声明的属性合成任何所需的ivars,除非您自己声明它们。

答案 1 :(得分:0)

是的,它可能会起作用。别这样做。它非常不灵活。它强制你在标题中声明ivars,它只适用于ivars,并且它不会给你任何控制读/写控件(或让你创建一个自定义的getter / setters)。暂时不再使用@访问控制是不合理的(不是move to non-fragile ivars以后,而且 之前有用)。

执行此操作的典型方法是使用带有类别的+Protected标头。例如,您可以像这样创建一个头文件Superclass+Protected.h

@interface Superclass (Protected)
@property (weak, nonatomic) SCNScene * scnScene;
@end

然后将其导入允许访问scnScene的任何实现文件中。请注意,您可以根据需要制作此readonly,因此内部可写,但对于受保护的实施,它只是可读的,而且对公众来说,它是不可见的。

这比文字"受保护"更灵活。因为您可以将此标头导入适当的任何其他实现。所以它也可以相当于C ++的朋友。"显然命名文件并提供一些标题注释可能有助于让调用者知道他们是否应该或不应该导入此文件。

对于没有强制执行访问控制的任何投诉(不是您提出访问控制,而是针对任何人),@protected也没有。 If I call valueForKeyPath:, I can access protected ivars, too. ObjC帮助您创造"没有非法入侵的标志"这样来电者就知道他们什么时候出现在他们不应该去的地方。它并没有试图阻止程序访问自己的内存空间。 (这将是徒劳的目标;您总是可以读取私有变量并以允许原始内存访问的任何语言调用私有函数;访问控制点是帮助调用者编写正确的代码,而不是阻止他们做任何事情。)