Difference between @property and ivar in Xcode 4.5
Asked Answered
O

2

12

Previously I have always seen example of use of properties and iVars like this...

Inside SomeClass.h

@interface SomeClass : NSObject {
    NSString *_someString;
}

@property NSString *someString;

@end

Then in SomeClass.m

#import "SomeClass.h"

@implementation SomeClass

@synthesize someString = _someString;

@end

More recently (in the WWDC 2012 videos) I've heard that we no longer need @synthesize and it's recommended to just use the @property without it's associated iVar.

So the above would change to...

SomeClass.h

@interface SomeClass : NSObject

@property NSString *someString;

@end

SomeClass.m

#import "SomeClass.h"

@implementation SomeClass

@end

This is just using the @property and no ivar. This makes sense and I have been using it.

However, I have also seen examples of...

SomeClass.h

@interface SomeClass : NSObject

@end

SomeClass.m

#import "SomeClass.h"

@interface SomeClass () {
    NSString *someString;
}

@end

@implementation SomeClass

@end

In this they just have a private iVar and no @property.

So what's the difference? I understand that the @property gives the accessor methods too but you don't have to override the accessor methods. You can just use default accessors.

So when would you use @property and not an ivar and when would you use just an ivar and not a @property? And why wouldn't you just get rid of ivars completely and just use @properties? If they need to be private then just use them inside the interface extension in the .m.

Quick edit in response to an answer about memory management. I'm using ARC and for me it would seem that I have more control over memory management with using strong and weak @properties than I do with using iVars.

I hope the question is clear enough.

Thanks

Oxheart answered 18/10, 2012 at 13:16 Comment(4)
Note that your very first example above is bad. In it, you have a someString property with a default backing iVar named _someString and a second iVar that has no connection to the property but is named someString just to cause pain. :-)Wenoa
@Phillip Mills, corrected it now.Oxheart
@property gives you the ability to use KVO where a regular iVar does not. Other than what you've already mentioned, I don't know of any other advantages/disadvantages.Migrant
So essentially, both give access to the same levels of memory management. iVars don't have getters and setters whereas properties do. Properties allow for use of KVO and iVars don't. I'll stick to using properties then :DOxheart
L
2

In general you can always use properties. If you have "assign" property you can use ivar beause you don't need any memory management in your getters/setters. But if you should retain objects it is just inconvinient to use ivars because you have to manually retain/release them while properties do that for you.

Also If you use ivars you don't have control over setting/getting values. In general it is a bad practive to use public fields instead of getters or setters. For example it is not ok if you can set negative value for field that store person's age.

And you can't use KVO with ivars

Lienlienhard answered 18/10, 2012 at 13:24 Comment(6)
But if I'm using ARC then all that is done for me anyway. For me it would seem that using properties with strong and weak gives me more memory control without having to use iVars at all.Oxheart
You can certainly say __weak NSString* _string and have the same level of control as @property (weak) NSString* stringMigrant
1) If you use ivars you don't have control over setting/getting values. In general it is a bad practive to use public fields instead of getters or setters. For example it is not ok if you can set negative value for field that store person's age. 2) You can't use KVO with ivarsLienlienhard
Thanks, I think I'll stick with @properties then :D I kind of had that in my mind anyway but I think the responses from here have confirmed my decision :DOxheart
I updated my answer with info from my comment to cover more advantages of properties:)Lienlienhard
I think you are totally wrong about relationship between properties and ARC. ARC works on ivars the same as on properties. When ARC is turned on, you never call retain/release on anything anymore, including on ivars. If you try, you will get a compiler warning.Hirz
B
-1

I think its depends on fact that you have access to public ivars with "->" syntax. Maybe previously, if you declare a readonly property without @private ivar you can access to it ivar with "->" syntax. (maybe its breaks encapsulation).

But now if you declare something like this

{
@private NSArray *a;
@protected NSArray *b;
@public NSArray *c;
}
@property (nonatomic, retain) NSArray *d; 

You can access with "->" only to "c" ivar, just try this code. with a,b and d it will be warning or error.

If it somehow helps, I will be glad.

Buzzer answered 18/10, 2012 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.