ARC Objective-C and iOS SDK Instance Variables

Do we intend to convert all of our instance variables that we want to store in private properties, or am I missing something obvious?

@interface SomethingElse : Something { NSMutableArray *someArray; } 

In this example, someArray is initialized in the method using [NSMutableArray initWithObject: someObject], but is not saved.

In my specific situation, I am updating the game, there are many instance variables, so I want to make sure that I am doing it correctly for future versions of sdk.

+7
source share
6 answers

Should we convert all the local variables that we want to save into private properties or am I missing something obvious?

First, the variable you showed in your example is an instance variable, not a local variable. Local variables are declared inside a code block (for example, inside a function or method or inside some sub-block, such as the body of a conditional statement) and have a lifetime limited by the execution of the block in which they are declared. Instance variables are declared in the class; each instance of this class gets its own copy of the instance variables declared by the class.

Secondly, no, you do not need to convert all your instance variables to properties. Instance variables are considered strong references in ARC by default. A property is simply a promise that a class provides certain access methods with specific semantics. Having an instance variable does not mean that you must provide the means of access for this ivar. (Some may say that you should, but you should not.)

+17
source

A @property is the same as an instance variable unless you use another default storage modifier, which is strong for objects. For example, if you want @property (copy) NSString *s; used an instance variable and didn't think about calling the copy every time you set the variable, or use @property (which is easier).

+3
source

The ARC retain version is called strong .

Basically, you would declare it using something like:

 @property (strong) NSMutableArray *someArray; 

See What is the "strong" do keyword for details.

Generally, it is better to use properties instead of local variables, since properties provide you accessors / setters for "free" and are usually easier to use.

+1
source

You describe the BAD_ACCESS problem in some of your other comments. Something is happening here. In ARC, your Ivars are strong, unless otherwise indicated (and in non-ARC they are not going to be exempted from your name).

For example, this ARC code works fine, without BAD_ACCESS, when you post other answers in your comments:

 @interface ArcTestViewController () { NSMutableArray *_someArray; } @end @implementation ArcTestViewController - (void)dealloc { _someArray = nil; } - (void)viewDidLoad { [super viewDidLoad]; _someArray = [[NSMutableArray alloc] initWithObjects:@"Mo", @"Larry", @"Curly", nil]; } - (IBAction)checkIvarTouchUpInside:(id)sender { NSLog(@"%s _someArray = %@", __FUNCTION__, _someArray); } @end 

You may need to show us your example when you receive your BAD_ACCESS, because it must be something else.

In response to the question “property” or “ivar”, although I sympathize with the argument “always use properties”, I personally use properties for something, for which I need to provide external accessors, otherwise I use personal ivars (and not in .h, but rather in the private interface in the .m file). This makes my public interfaces in my .h files really clean and clear when I return to them after a few months. If you take the “always use properties” approach, I would only say that your public declaration of these properties should be as restrictive as possible (make the property private, if possible, make the public declaration of readonly property if you do not need to provide readwrite access and etc.).

By the way, Naming the properties and data types of the Cocoa Coding Guide is a good reference to best practices.

+1
source

With Obj-C 2.0 and later, there seems to be little reason to use iVars. I personally have not used it forever. Properties just do everything for you!

0
source

Thank you all for your answers.

If I call a method that needs an object (using the cocos2d engine method):

 [self schedule:@selector(someMethod) interval:3.0]; 

An object is dereferenced if I call it directly without putting it in the cocos2d scheduler:

 [self someMethod]; 

Then there is still a valid pointer. Just to check, I saved it and it stays around.

So, the question is, how do we force to keep the ARC from thinking that we ended up with it and released it?

Changing an instance variable in a private property does this safely, so we will see this as an answer.

0
source

All Articles