2

这个问题特别关注静态库/框架;换句话说,其他人最终会接触到的代码。

我在属性方面相当精通,因为我在 iOS 6 发布时就开始了 iOS 开发。我使用了在接口扩展中声明的隐藏属性来完成我所有的“私有”属性工作,包括readonly在我不希望其他人修改的面向公众的属性上以及readwrite在接口扩展中使用。

重要的是,如果我不允许,我希望使用这些静态库/框架的其他人访问这些属性,如果我让他们阅读,我也不希望他们编写这些属性。

我已经知道他们理论上可以创建自己的接口扩展并自己制作我的readonly属性readwrite,或者猜测隐藏属性的名称。

如果我想防止这种情况,我应该使用@private带有直接声明 ivars 的标签的 ivars 吗?这样做有潜在的失败吗?它真的让我获得了额外的安全措施,还是红鲱鱼?

4

2 回答 2

4

在 ARC 下,属性而不是实例变量支持的唯一模式是copy- 所以如果您需要copy使用属性。

如果您在该@implementation部分中声明私有实例变量:

@implementation MyClass
{
   // private instance vars
}

那么从课外访问它们需要付出很大的努力。正如您所说,访问“私有”属性只需猜测其名称 - 或使用告诉您的库调用。

为了安全值得吗?YMMV。但无论如何,它都是一个很好的编码实践。

附录

正如评论线索显示的那样,关于我认真努力的使用已经有很多讨论。

首先让我们明确一点:Objective-C 属于 C 语言家族,它们都允许程序员在保持语言的同时进行他们选择的任何事情[ *] - 如果你想要强类型,这些不是选择的语言,访问您的代码中的限制等。

第二,“努力”不是绝对的衡量标准!所以也许我应该选择“明显”这个词来限定它而不是“严重”。要访问私有属性只需要使用对象具有类型的标准方法调用id- 代码中几乎没有线索表明被调用的方法是隐藏的。要访问私有变量需要 API 调用(运行时函数或 KVC 调用)或一些指针操作 - 生成的代码看起来与标准变量赋值完全不同。所以它更明显

也就是说,除了使用 requires 之外copy,在 ARC 下,当私有实例变量可以使用时,没有充分的理由使用私有属性。对于私有变量fred比较:

self.fred = 42;   // property access, may involve a call (if not optimised out)
_fred = 42;       // common way to bypass the accessors and get at the underlying var
fred = 42;        // direct access

选择吧,没有正确的答案,但也没有错误的答案- 这是意见的领域(这当然是意见;-))。我经常会选择最后一个,私有变量——干净且简单。但是@RobNapier 在他的回答中更喜欢使用属性。


[*] 注意:一旦你考虑链接到外部代码,比如用汇编程序编写的,所有的赌注都可以使用任何语言。此时,您必须查看“硬件”(真实或虚拟)和/或“操作系统”以提供保护。

于 2013-12-18T23:12:53.083 回答
2

您应该在此处使用私有(“隐藏”)属性。不存在“安全”风险。这种情况下的“攻击者”是调用者。调用者可以完全访问进程中的所有内存。她可以访问您想要访问的框架中的任何内容,并且您绝对无法做任何事情来阻止它(您也不应该这样做)。在任何语言中都是如此。如果您知道自己在做什么,也可以绕过 C++ 中的“private:”指定。这一切都只是一天结束时的记忆。

保护你自己或你的框架免受调用者的伤害不是你的工作。你们都有相同的目标:正确的程序行为。您的目标是保护来电者免受自己的伤害。使他们难以错误地使用您的框架,并且易于正确使用。

因此,您应该使用导致最正确代码的工具。而那个工具是属性,除了 init 和 dealloc 之外,避免直接访问 ivar。

于 2013-12-19T01:38:27.407 回答