Objective c 以下使用objc@protected指令是否安全/合法?

Objective c 以下使用objc@protected指令是否安全/合法?,objective-c,properties,protected,Objective C,Properties,Protected,我必须将私有财产暴露给子类。 因为在objc AFAIK中没有“protectedproperties”这样的东西,所以我使用@protected指令来公开编译器合成的相应ivar 这个方法似乎有效,但是,我不确定我是否以某种不可取的方式影响了属性和弧的合成 我在这里使用了一个弱属性来显示编译器是如何强迫我将_弱修饰符与@protected指令一起使用的,也就是说,编译器似乎知道这两个声明以及它们之间的链接 超类.h文件 @interface Superclass : NSObject { @p

我必须将私有财产暴露给子类。 因为在objc AFAIK中没有“protectedproperties”这样的东西,所以我使用@protected指令来公开编译器合成的相应ivar

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

我在这里使用了一个弱属性来显示编译器是如何强迫我将_弱修饰符与@protected指令一起使用的,也就是说,编译器似乎知道这两个声明以及它们之间的链接

超类.h文件

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

@end
超类.m文件

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

@implementation Superclass
........
@end
@implementation Subclass
    // Can use _scnScene just fine
    _scnScene = .....
@end
子类.m文件

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

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

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

@interface Superclass : NSObject
@end

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

在类声明的上下文中,
protected
是实例变量的默认可见性,所以你的声明无效。事实上,以下声明:

@interface Superclass : NSObject
@end

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

是的,它可能会工作。不要这样做。这很不灵活。它强制您在头中声明IVAR,它只适用于IVAR,并且它不给您任何对读/写控件的控制(或者让您创建自定义getter/setter)。现在真的没有理由再使用
@
访问控件了(从年开始就没有了,以前也没有那么有用)

一种典型的方法是使用带有类别的
+受保护的
标题。例如,您可以创建一个头文件
Superclass+Protected.h
,如下所示:

@interface Superclass (Protected)
@property (weak, nonatomic) SCNScene * scnScene;
@end
然后将其导入允许访问
scnScene
的任何实现文件中。请注意,如果需要,您可以将此
设置为只读
,因此在内部它是可写的,但对于受保护的实现来说,它只是可读的,对于公众来说,它是不可见的

这比文字“protected”更灵活,因为您可以在适当的地方将此头导入任何其他实现。因此,它也可以相当于C++的“friend”。显然,命名文件并提供一些标题注释有助于让调用方知道是否应该导入此文件


对于任何关于这没有强制执行访问控制的投诉(不是你做的,而是对任何人做的),
@protected
也没有。ObjC帮助您创建“禁止侵入标志”,以便呼叫者知道他们何时到达了不该到达的地方。它不会试图阻止程序访问自己的内存空间。(这将是一个徒劳的目标;您始终可以用任何允许原始内存访问的语言读取私有变量和调用私有函数;访问控制的目的是帮助调用方编写正确的代码,而不是阻止他们执行任何操作。)

是的,它可能会起作用。不要这样做。这很不灵活。它强制您在头中声明IVAR,它只适用于IVAR,并且它不给您任何对读/写控件的控制(或者让您创建自定义getter/setter)。现在真的没有理由再使用
@
访问控件了(从年开始就没有了,以前也没有那么有用)

一种典型的方法是使用带有类别的
+受保护的
标题。例如,您可以创建一个头文件
Superclass+Protected.h
,如下所示:

@interface Superclass (Protected)
@property (weak, nonatomic) SCNScene * scnScene;
@end
然后将其导入允许访问
scnScene
的任何实现文件中。请注意,如果需要,您可以将此
设置为只读
,因此在内部它是可写的,但对于受保护的实现来说,它只是可读的,对于公众来说,它是不可见的

这比文字“protected”更灵活,因为您可以在适当的地方将此头导入任何其他实现。因此,它也可以相当于C++的“friend”。显然,命名文件并提供一些标题注释有助于让调用方知道是否应该导入此文件


对于任何关于这没有强制执行访问控制的投诉(不是你做的,而是对任何人做的),
@protected
也没有。ObjC帮助您创建“禁止侵入标志”,以便呼叫者知道他们何时到达了不该到达的地方。它不会试图阻止程序访问自己的内存空间。(这将是一个徒劳的目标;您始终可以用任何允许原始内存访问的语言读取私有变量和调用私有函数;访问控制的目的是帮助调用方编写正确的代码,而不是阻止他们做任何事情。)

p.S.当然,可以使用ivar(\u scnScene)直接在子类中,我将绕过Super可能具有的任何setter/getter,但我更关心ARC等问题。
@protected
不会干扰ARC,它定义ivars可见性。P.S。当然,通过在子类中直接使用ivar(_scnScene),我将绕过Super可能具有的任何setter/getter,但我更关心ARC等问题。
@protected
不会干扰ARC,它定义了ivar可见性。感谢您的回复。这也是我对private行为的期望(在.m文件中定义)属性。(在我完成之前在上面发布了我的上一条评论,所以在这里完成)这正是我对私有(在.m文件中定义)属性行为的期望,也是我最初实现超类和子类的方式。但是,我没有访问