@interface 或 @implementation 中的私有 ivar
是否有任何理由在 @interface
中声明私有 ivar 而不是 @implementation
?
我在互联网上看到这样的代码(包括 Apple):
Foo.h
@interface Foo : NSObject {
@private
id _foo;
}
@end
Foo.m
@implementation Foo
// do something with _foo
@end
头文件定义类的公共接口,而私有 ivar 是...嗯……私人的。那么为什么不这样声明呢?
Foo.h
@interface Foo : NSObject
@end
Foo.m
@implementation Foo {
@private
id _foo;
}
// do something with _foo
@end
Is there any reason to declare a private ivar in @interface
instead of @implementation
?
I see code like this all over the internet (including documentation provided by Apple):
Foo.h
@interface Foo : NSObject {
@private
id _foo;
}
@end
Foo.m
@implementation Foo
// do something with _foo
@end
The header file defines the public interface of a class, whereas a private ivar is... well... private. So why not declare it like this?
Foo.h
@interface Foo : NSObject
@end
Foo.m
@implementation Foo {
@private
id _foo;
}
// do something with _foo
@end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在
@implementation
中声明实例变量是 Obj-C 的一项最新功能,这就是为什么您在@interface
中看到大量带有它们的代码 - 没有其他选择。如果您使用的编译器支持在声明实现中声明实例变量,则可能有最好的默认设置 - 仅当其他人需要访问它们时才将它们放入接口中。
编辑:附加信息
在实现中声明的实例变量隐式隐藏(实际上是私有的)并且可见性无法更改 -
@public
、@protected
和@private
不会产生编译器错误(至少对于当前的 Clang 而言),但会被忽略。Declaring instance variables in the
@implementation
is a recent feature of Obj-C, this is why you see a lot of code with them in the@interface
- there was no other choice.If you are using a compiler which supports declaring instance variables in the implementation declaring them there is probably the best default - only put them in the interface if they need to be accessed by others.
Edit: Additional Info
Instance variables declared in the implementation are implicitly hidden (effectively private) and the visibility cannot be changed -
@public
,@protected
and@private
do not produce compiler errors (with the current Clang at least) but are ignored.如果您需要针对旧系统或 Xcode 版本的编译器支持,您会喜欢
@interface
。如果您确定不需要向后兼容性,我建议最好将其放在
@implementation
中。You would favor
@interface
if you need compiler support targeting older systems or releases of Xcode.If you are certain you will not need that backwards compatibility, I'd say it's best to place it in the
@implementation
.指令@public、@protected 和@private 是
不绑定在 Objective-C 中,它们是编译器提示
变量的可访问性。
它不会限制您访问它们。
示例:
gcc 编译器会输出:
对于每个对“私有”成员 y 的“不适当”访问,
,但无论如何都会编译它。当运行时,你会得到
So it确实取决于你不以这种方式编写访问代码,但因为 objc 是 C 的超集,
C 语法工作得很好,并且所有类都是透明的。
您可以设置编译器将这些警告视为错误并进行保释——但 Objective-C 内部并未针对这种严格性进行设置。动态方法分派必须检查每个调用的范围和权限(slooooowwwww...),因此除了编译时警告之外,系统还希望程序员尊重数据成员范围。
在 Objective-C 中,有几种获取成员隐私的技巧。
一是确保将类的接口和实现分别放在单独的 .h 和 .m 文件中,并将数据成员放在实现文件(.m 文件)中。
那么导入头文件的文件就无法访问数据成员,只能访问类本身。
然后在标头中提供访问方法(或不)。您可以实现 setter/getter 函数
如果您愿意,可以在用于诊断目的的实现文件中,并且它们将是可调用的,
但不能直接访问数据成员。
示例:
编译器将对这种公然的恶作剧发出警告,但会继续
并相信你知道自己在做什么(真的吗?),并且你有自己的理由(是吗?)。
看起来工作量很大?容易出错?耶宝贝!
在使用神奇的 C 技巧和像这样的肉丸手术之前,请先尝试重构代码。
但它就在那里。祝你好运。
The directives @public, @protected, and @private are
not binding in objective-C, they are compiler hints about
the accessibility of the variables.
It DOES NOT RESTRICT YOU from accessing them.
example:
The gcc compiler spits out :
once for each "innapropriate" access to "private" member y, but compiles it anyway.
When run you get
So it really is up to you NOT to write access code this way, but because objc is a superset of C,
C syntax works just fine, and all classes are transparent.
You can set the compiler to treat these warnings as errors and bail -- but objective-C is not set up internally for this kind of strictness. The dynamic method dispatch would have to check for scope and permission for each call ( slooooowwwww... ) , so beyond a compile-time warning, the system expects the programmer to respect data member scoping.
There are several tricks to getting privacy of members in objective-C.
One is to make sure you put the interface and implementations of your class in separate .h and .m files, respectively, and put the data members in the implementation file (the .m file).
Then the files that import the headers do not have access to the data members, only the class itself.
Then provide access methods (or not) in the header. You can implement setter/getter functions
in the implementation file for diagnostic purposes if you want and they will be callable,
but direct access to the data members will not be.
example:
The compiler will issue warnings for such blatant shenanigans, but will go ahead
and trust that you know what you are doing (really?), and that you have your reasons (do you?).
Seem like a lot of work? Error Prone? Yay Baby!
Try refactoring your code first before resorting to magic C tricks and meatball surgery like this.
But there it is. Good luck.