【问题标题】:Objective C - Make iVars hiddenObjective C - 隐藏 iVar
【发布时间】:2012-07-29 07:27:00
【问题描述】:

这是我的问题。

假设我有一个名为 WebServiceBase.h 的类。我需要在名为 NSString *requestData 的类中添加一个 iVar。但我不需要将该 iVar 添加到头文件中并使其对外部人员可见。 (如果我将其作为类库分发)

我还需要能够在从 WebServiceBase.h 扩展的其他类中访问此 requestData iVar。 (这些扩展类是我写的,不是外人写的)

我尝试在类扩展中声明 requestData iVar。但是它对扩展类不可见。

有什么解决办法吗?我需要保护我的数据并使其对外界隐藏。

【问题讨论】:

标签: iphone objective-c ios ios5


【解决方案1】:

您可以通过 @protected 关键字将您的 ivars 定义为受保护,这意味着您的类和所有子类都可以毫无问题地访问它,但编译器不会允许其他不从您的基类继承的类类:

@interface Foo : NSObject
{
@protected
    NSObject *a;
}

就这么简单,并且已经为您提供了从 Objective-C 获得的所有安全性。

【讨论】:

  • 您仍然可以访问它,例如 KVC 默认在它们上工作。如果为此 ivar 禁用了 KVC,那么您还拥有运行时...Objective-C 确实不允许私有 ivars、属性或方法,就这么简单。
  • 亲爱的史蒂文,你是 100% 正确的。我们不能在子类中使用那些 iVar。如果我将它们声明为属性,除非我将它们声明为只读,否则任何人都可以更改这些属性值。我需要保护我的数据。而且,如果我在 .h 文件中声明它们,任何人都可以看到我的 iVar 并对类结构有所了解。我不想。
  • 我们知道如果我在 .m 文件中这样声明 @synthesize requestData = _requestData 这将生成一个名为 _requestData 的 iVar。(顺便说一句,这是 Xcode 4.5 中的默认行为)。在这种情况下,_requestData iVar 在子类中也不可见。
  • @charith 就像我已经说过的那样;它仍然可以通过 KVC 访问,但不仅适用于您的子类,而且适用于所有人。你不能隐藏 ivars,即使你把它们放到实现中也不能!您不应该为此使用 KVC,因为它不能解决您的问题,只会增加开销,而只需在您的界面中将您的 ivar 声明为 @protected,这至少可以为您提供编译时保护,并且您无法实现更多功能无论如何,Objective-C。
  • @charith 另一种方法是在您的 .m 文件中创建一个属性,然后在您的子类中创建一个私有类别。但是我不能强调这并不能解决您的运行时问题,而这根本无法解决!
【解决方案2】:

你可以在@implementation 块中有一个ivar 定义块。

【讨论】:

  • 是的。但是我怎样才能声明内存管理语义呢?如果我在 ARC 下运行,那么编译器如何处理 iVar NSString *requestData 的内存?
  • 就是这样。你不需要做任何事情。除非你希望它变弱,在这种情况下你使用__weak
  • 亲爱的 ranReloaded 和 Steven,我又检查了一遍。如果我在 @implementation 块中声明一个 iVar,那么我不能在该类的其他扩展类中使用该 iVar。感谢您的反馈以实现这一目标。
  • 没错。所以你想对除子类之外的所有人隐藏 ivars 吗?我认为你不能做到这一点......
【解决方案3】:

有两种方式,你可以选择你喜欢的一种。

    1).h file
    @interface YourClass
    {
    }

    .m file
    @interface YourClass ()
    @property (nonatomic, retain) NSString *title;
    @end

    @implementation YourClass

    @synthesize title;

    //your method


    2) .h flie 
    @interface YourClass
    {
    }

    .m file
    @implementation YourClass  
    {  
        NSString *title;   
    }  

//your method

【讨论】:

  • 亲爱的,如果我们实施您的解决方案 1 和 2,那么我不能在我的其他扩展类中使用标题 iVar。我应该可以在我的扩展课程中使用这个标题。
  • @charith 对不起,我忘了你想在你的扩展课程中使用。所以请使用方法1。
  • @charith 我搜索一个答案也许可以帮助你,看看这个stackoverflow.com/questions/6659383/protected-in-objective-c
【解决方案4】:

声明一个在另一个 .h 文件中定义 ivar 的类扩展。称之为myclass-private.h。然后在你的主类和子类中导入该标题。

【讨论】:

  • 这并没有真正满足他/她的要求。其他类仍然可以很容易地导入 myclass-private.h。将名称设为私有并不会使其私有:)。此外,他们希望将库中的内容隐藏起来以防逆向工程,而这也不行。
  • 我假设您没有将该头文件与您的库一起分发。您可以将它导入您自己在库中编写的子类中,然后不释放该标头。当然,这不是真正的保护,但它是 obj-C 中最好的!
猜你喜欢
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
相关资源
最近更新 更多