Objective-C: _variable

 ̄綄美尐妖づ 提交于 2020-01-14 04:13:14

问题


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:

@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 (i.e. _pages replaces self.pages) like so:

_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?

Thanks for your help.


回答1:


_pages is the name of the object's ivar. pages is the property name which is different.
So, @synthesize pages = _pages; finally tells that pages is the property for the ivar _pages.

You will encouter the ivar direct access via _pages in initializers and dealloc methods. Every where else, the property name is used to get/set its value.




回答2:


When you use a simple assignation :

_pages = ...

you simply set the instance variable.

When you use a property assignation :

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.




回答3:


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).

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.). Typically, these ownership operations take place in init and dealloc.

On the other hand, the property provides the 'designated' access point for the ivar. The property methods (the setter and getter) may perform additional operations required for the proper management of the ivar. So accessing the ivar directly (as a usage pattern) is not recommended, even within the owning objects. For example, a setter might be implemented like this:

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

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

    [pages release];
    _pages = newValue;
}



回答4:


_pages is the instance variable and pages is the property name. 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]];

So the only actual object is the instance variable _pages and so only this can be memory managed.

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



回答5:


You can reference an @synthesized property either as instanceVariableName or as self.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. 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.

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). 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.

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.



来源:https://stackoverflow.com/questions/8545363/objective-c-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!