【问题标题】:private property in Objective CObjective C 中的私有属性
【发布时间】:2011-08-04 07:52:51
【问题描述】:

有没有办法在 Objective C 中声明私有属性?目标是从合成的 getter 和 setter 中受益,实现某种内存管理方案,但不向公众公开。

尝试在类别中声明属性会导致错误:

@interface MyClass : NSObject {
    NSArray *_someArray;
}

...

@end

@interface MyClass (private)

@property (nonatomic, retain) NSArray   *someArray;

@end

@implementation MyClass (private)

@synthesize someArray = _someArray;
// ^^^ error here: @synthesize not allowed in a category's implementation

@end

@implementation MyClass

...

@end

【问题讨论】:

  • 为什么要有私有财产?什么时候可以直接在实例方法中访问*_someArray
  • 私有属性是放置 ivars 延迟加载逻辑等内容的好地方

标签: objective-c


【解决方案1】:

我这样实现我的私有属性。

MyClass.m

@interface MyClass ()

@property (nonatomic, retain) NSArray *someArray;

@end

@implementation MyClass

@synthesize someArray;

...

这就是你所需要的。

【讨论】:

  • 进一步扩展,Objective-C 并没有私有方法的概念。你可以调用任何你喜欢的方法,只要你知道名字。这就是允许您在 Apple 的类中调用私有方法的原因,即使它们不存在于标头中。
  • “这就是你所需要的。” :D 从来没有用这么多代码来定义一个简单的属性
  • 这些天你甚至不需要@synthesize
  • 我以为你必须在 .h 文件中声明属性?
  • 确保不要像这样@interface MyClass (DontPutMeHere)在.m文件中为您的类别设置名称@否则自动合成将不起作用
【解决方案2】:

A. 如果您想要一个完全私有的变量。不要给它一个属性。
B.如果您想要一个可从类的封装外部访问的只读变量,请使用全局变量和属性的组合: p>

//Header    
@interface Class{     
     NSObject *_aProperty     
}

@property (nonatomic, readonly) NSObject *aProperty;

// In the implementation    
@synthesize aProperty = _aProperty; //Naming convention prefix _ supported 2012 by Apple.

使用 readonly 修饰符,我们现在可以在外部任何地方访问该属性。

Class *c = [[Class alloc]init];    
NSObject *obj = c.aProperty;     //Readonly

但在内部,我们不能在 Class 中设置 aProperty:

// In the implementation    
self.aProperty = [[NSObject alloc]init]; //Gives Compiler warning. Cannot write to property because of readonly modifier.

//Solution:
_aProperty = [[NSObject alloc]init]; //Bypass property and access the global variable directly

【讨论】:

    【解决方案3】:

    这取决于你所说的“私人”是什么意思。

    如果您只是指“未公开记录”,您可以轻松地在私有标头或 .m 文件中使用 class extension

    如果您的意思是“其他人根本无法调用它”,那么您就不走运了。任何人只要知道它的名称就可以调用该方法,即使它没有公开记录。

    【讨论】:

    • > "任何人只要知道它的名字就可以调用这个方法,即使它没有被公开记录。" - 最好的安全计算:-(
    • @BronDavies objective-c 使用“消息传递”范例,您可以在其中向对象发送消息。属性的名称只是消息的内容,属性的值只是对象对消息的响应。如果您希望任何消息传递系统的安全性,您需要使用加密。属性名称可能来自私钥,并且可能每 30 秒更改一次。如果您需要,安全性在 obj-c 中当然是可能的。我无法想象你为什么会……我将我的属性设为私有,以便我以后可以在不破坏外部代码的情况下更改它们。
    【解决方案4】:

    正如其他人所指出的,(目前)没有办法在 Objetive-C 中真正声明私有属性。

    您可以尝试以某种方式“保护”属性的其中一件事是创建一个基类,该基类的属性声明为readonly,并且在您的子类中您可以重新声明与readwrite 相同的属性。

    Apple 关于重新声明属性的文档可在此处找到:http://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW19

    【讨论】:

    • 我发现 {} 的使用有点繁琐,我只想在这里指出这一点;在 .m 文件中,我必须在 {} 块之后声明“私有”属性; (请原谅糟糕的格式...)@interface MyClass() { SKProductsRequest* _request; NSMutableArray* _productLocales; } @property (strong, nonatomic) SKProductsRequest *request; @end @implementation MyClass @synthesize request = _request; ...
    猜你喜欢
    • 2013-11-27
    • 2011-10-01
    • 2013-10-06
    • 2012-01-05
    • 2015-08-19
    • 2011-04-09
    • 1970-01-01
    • 2014-01-14
    • 2011-12-02
    相关资源
    最近更新 更多