目标C中的私有财产


72

有没有办法在目标C中声明私有财产?目的是受益于实现某种内存管理方案但尚未公开的综合获取器和设置器。

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

@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直接在实例方法内部访问?
黑蛙


4
私有财产是放置诸如ivars的延迟加载逻辑之类的好地方
Michael Lang

Answers:


106

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

MyClass.m

@interface MyClass ()

@property (nonatomic, retain) NSArray *someArray;

@end

@implementation MyClass

@synthesize someArray;

...

这就是您所需要的。


4
为了对此进行扩展,Objective-C实际上没有私有方法的概念。只要知道名称,就可以调用任何您喜欢的方法。这是允许您在Apple的类中调用私有方法的方法,即使它们在标头中不存在。
Todd Yandell

33
“这就是您所需要的。” :D从未使用太多代码来定义简单的属性
stoefln 2012年

13
这些天,您甚至都不需要@synthesize

1
我以为您必须在.h文件中声明属性?
cheznead

2
确保不要在.m文件中为您的类别设置名称,@interface MyClass (DontPutMeHere)否则将无法自动合成
Christoph

10

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

//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

但是在内部,我们无法在类内设置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

7

这取决于您所说的“私人”。

如果您只是说“未公开记录”,则可以在私有标头或.m文件中轻松使用类扩展名

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


>“即使知道该方法的名称,任何人都可以调用该方法,即使该方法未公开记录也是如此。” -最好的安全计算:-(
Bron Davies

@BronDavies Objective-c使用“消息传递”范例将消息发送到对象。属性的名称只是消息的内容,而属性的值只是对象对消息的响应。如果要确保任何邮件系统的安全性,则需要使用加密。属性名称可能是从私钥派生的,并且可能每30秒更改一次。如果需要,在obj-c中肯定可以实现安全性。我无法想象您为什么会......将我的属性设为私有,以便以后可以更改它们而不会破坏外部代码。
Abhi Beckert

6

正如其他人所指出的那样,(当前)无法在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文件中,我必须在{}块之后声明“ private”属性。(请原谅糟糕的格式...) @interface MyClass() { SKProductsRequest* _request; NSMutableArray* _productLocales; } @property (strong, nonatomic) SKProductsRequest *request; @end @implementation MyClass @synthesize request = _request; ...
SonarJetLens 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.