使用隐藏属性与私有iVars

时间:2013-12-18 22:54:36

标签: ios objective-c properties ivar

这个问题专门针对静态库/框架;换句话说,其他人最终会触及的代码。

我非常精通属性,因为我在iOS 6发布时开始了iOS开发。我已经使用了在接口扩展中声明的隐藏属性来完成我的所有“私有”属性工作,包括在面向公众的属性上使用readonly我不希望其他人修改和readwrite在接口扩展中。< / p>

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

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

如果我想阻止这种情况,我是否应该使用带有@private标签的ivars直接声明的ivars?这样做是否有潜在的挫折?它实际上是否为我提供了额外的安全措施,还是红鲱鱼呢?

2 个答案:

答案 0 :(得分:4)

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

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

@implementation MyClass
{
   // private instance vars
}

然后需要认真努力从课外访问它们。正如您所说,访问“私有”属性只需要猜测它的名称 - 或使用告诉您的库调用。

安全性是否值得?因人而异。但不管它是一个很好的编码实践。

<强>附录

正如评论记录显示,我对认真努力的使用进行了大量讨论。

首先要明确一点:Objective-C属于C语言系列,它们都允许程序员在语言中保留时所选择的任何内容[*] - 这些不是如果您想要强类型,访问限制等等,请选择语言。 代码。

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

尽管如此,除了需要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

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


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

答案 1 :(得分:2)

您应该在此处使用私有(“隐藏”)属性。没有“安全”风险。此场景中的“攻击者”是呼叫者。调用者可以完全访问进程中的所有内存。她可以访问你想要的框架中的任何东西,你绝对没有办法阻止它(你也不应该)。任何语言都是如此。如果您知道自己在做什么,也可以绕过C ++中的“private:”名称。这一切都只是在一天结束时的记忆。

保护自己或您的框架不受呼叫者的影响。你们都有相同的目标:正确的程序行为。您的目标是保护呼叫者免受他们自己的伤害。使他们难以正确使用您的框架并且易于正确使用它。

因此,您应该使用能够获得最正确代码的工具。该工具是属性,并且除了在init和dealloc之外,避免直接进行ivar访问。