简体   繁体   English

目标C:_variable

[英]Objective-C: _variable

OK, this must have been asked before but I looked like mad and found nothing: 好的,这一定是以前问过的,但是我看上去很生气,什么也没发现:

I have a simple array in my iphone app which I define like so: 我在iPhone应用程序中有一个简单的数组,定义如下:

@property (nonatomic, strong) NSArray *pages;
@synthesize pages = _pages;

I've seen this in Apples sample code and thought this is a nice short-cut for writing self.pages (ie _pages replaces self.pages) like so: 我已经在Apple的示例代码中看到了这一点,并认为这是编写self.pages(即_pages替换self.pages)的一个不错的捷径,如下所示:

_pages = [[NSArray alloc] init];

but then Apple has this again (not exactly like this, but it appears as if they keep swapping randomly): 但是苹果又有这个了(不完全是这样,但看起来好像他们一直在随机交换):

self.pages = [NSKeyedUnarchiver unarchiveObjectWithData:contents];

And finally: 最后:

[_pages release];

Which totally confuses me. 这让我完全困惑。 What would be the difference between _pages and self.pages? _pages和self.pages有什么区别?

Thanks for your help. 谢谢你的帮助。

_pages is the name of the object's ivar . _pages是对象的ivar的名称。 pages is the property name which is different. pages是不同的属性名称。
So, @synthesize pages = _pages; 因此,@ @synthesize pages = _pages; finally tells that pages is the property for the ivar _pages . 最后告诉pages是ivar _pages的属性。

You will encouter the ivar direct access via _pages in initializers and dealloc methods. 您将通过初始化程序和dealloc方法中的_pages限制ivar直接访问。 Every where else, the property name is used to get/set its value. 在其他所有位置,属性名称都用于获取/设置其值。

When you use a simple assignation : 使用简单分配时:

_pages = ... _pages = ...

you simply set the instance variable. 您只需设置实例变量。

When you use a property assignation : 使用属性分配时:

self.pages = ... self.pages = ...

It call a method synthesized automatically by the compiler (or defined by you) and for synthesizing this method, it checks the type of the property (retain, assign, ...) and writes code to match this type of property. 它调用由编译器自动合成的方法(或由您定义),并且为了合成该方法,它检查属性的类型(retain,assign,...)并编写代码以匹配该类型的属性。

This difference comes from common naming and usage practices. 这种差异来自常见的命名和使用习惯。

Both the instance variable and the property refer to the same object. 实例变量和属性都引用同一个对象。 The difference in naming is used for pointing out the difference between the ivar ( _pages ) and the property ( pages ). 命名上的差异用于指出ivar( _pages )和属性( pages )之间的差异。

The ivar is owned by the instances of the class and it's up to them to handle ownership operations for it (alloc, retain, release, etc.). 该ivar由该类的实例拥有,并且由它们处理它的所有权操作(分配,保留,释放等)。 Typically, these ownership operations take place in init and dealloc . 通常,这些所有权操作在initdealloc

On the other hand, the property provides the 'designated' access point for the ivar. 另一方面,该属性为ivar提供了“指定”访问点。 The property methods (the setter and getter) may perform additional operations required for the proper management of the ivar. 属性方法(setter和getter)可能会执行正确管理ivar所需的其他操作。 So accessing the ivar directly (as a usage pattern) is not recommended, even within the owning objects. 因此,不建议直接访问ivar(作为使用模式),即使在拥有对象内也是如此。 For example, a setter might be implemented like this: 例如,setter可以这样实现:

- (void) setPages:(NSArray *)newValue {
    [newValue retain];

    // additional operations that you will miss if you use the ivar 
    [someObject someUsefulOperationThatIsReallyNeeded];

    [pages release];
    _pages = newValue;
}

_pages is the instance variable and pages is the property name. _pages是实例变量,而pages是属性名称。 The property is accessed via the getter and setter methods pages and setPages: object.pages is equivalent to [object pages] or for your example `[self setPages:[NSKeyedUnarchiver unarchiveObjectWithData:contents]]; 可通过getter和setter方法的pagessetPages:访问该属性setPages: object.pages等效于[object pages]或在您的示例中为[[self setPages:[NSKeyedUnarchiver unarchiveObjectWithData:contents]];

So the only actual object is the instance variable _pages and so only this can be memory managed. 因此,唯一的实际对象是实例变量_pages ,因此只能对其进行内存管理。

The property and synthesiser code in effect give the same as this code (in practice there could be extra code for memory management and thread locking 有效的属性和合成器代码与此代码相同(实际上可能存在用于内存管理和线程锁定的额外代码

@interface MyClass
{
 ...
    NSArray *_pages 
}

- (NSArray*)pages;
- (void)setPages:(NSArray*)newValue;

@end

@implementation MyClass
- (NSArray*)pages
{
    return _pages;
}
- (void)setPages:(NSArray*)newValue
{
    _pages = newValue; // Note in non ARC code there would be some memort managment here
}

@end

You can reference an @synthesized property either as instanceVariableName or as self.propertyName . 您可以将@synthesized属性引用为instanceVariableNameself.propertyName The two names can be the same or different. 这两个名称可以相同或不同。

When you reference as instanceVariableName , and modify the value, none of the retain/copy logic of the associated property is applied -- you're just referencing the "raw" variable. 当您引用instanceVariableName并修改值时,将不应用任何关联属性的保留/复制逻辑-您仅引用“ raw”变量。 When you reference self.propertyName , the retain/copy logic is applied, and, eg, if the property is declared with "retain" then the old value will be released and the new value retained. 当您引用self.propertyName ,在保留/复制逻辑应用,例如,如果属性与“保留”,则旧值将被释放,新的价值保留声明。

When assigning an already-retained value (such as one from alloc/init) to a property, it's simpler (if this an initialization where the property was previously nil ) to assign to instanceVariableName and skip the need to release the value (so that the net number of retains will be 1 at the end of the operation). 当指定一个已经保存的值(如一个从分配/初始化)一个属性,它更简单(如果初始化其属性是以前nil )分配给instanceVariableName并跳过需要release值(这样净retains数将在操作结束时为1)。 But when assigning a value that is not retained (other than an autoreleased retain ) to a property, you want to have the property's retain occur, so you'd use the self.propertyName notation. 但分配是不是值时retained (不是其他autoreleased retain的属性),你想拥有的财产的retain会发生,所以你最好使用self.propertyName符号。

Using a leading "_" for an instance variable that is also a property is a simple convention to keep these two apart, and avoid accidentally referencing one (by adding/removing self erroneously) when you meant the other. 对于作为属性的实例变量使用前导“ _”是一种简单的约定,可以将两者分开,并避免在意指另一个时意外地引用其中一个(通过错误地添加/删除self )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM