1

I'm starting my adventure with Objective-C and iOS and I've got one thing that I don't know how to use correctly and this is literally blowing my mind.

Many tutorials have private class variables in .m files defined like this:

@interface ViewController (){
    @property (nonatomic, strong) NSMutableArray *myArray;
}

or like this:

@implementation ViewController
        NSMutableArray *myArray;
@end

In the first example I can use _myArray instead of self.myArray, which I like, but should I put all my private variables in interface files? What's the difference between those two variables? When should I use one instead of another, and which is safer?

Bryan Chen
  • 45,816
  • 18
  • 112
  • 143
Roval
  • 508
  • 1
  • 4
  • 21
  • 1
    one doesn't work and another one works in an unexpected way (i.e. doesn't work). – Bryan Chen Jul 31 '14 at 09:03
  • possible duplicate of [What is the difference between ivars and properties in Objective-C](http://stackoverflow.com/questions/4172810/what-is-the-difference-between-ivars-and-properties-in-objective-c) – Bryan Chen Jul 31 '14 at 09:08
  • 2
    Advice: Always use @property and self. syntax unless you really can't. – Antzi Jul 31 '14 at 09:11

5 Answers5

3

The difference is that:

  • _myArray is instance variable.

  • self.myArray is calling a getter method on your object.

  • Using self.myArray = nil makes the variable go through its setter and therefore release the object when ARC is not used).

    • If the property is declared with atomic (default value) which means access the variable is thread-safe with the cost of performance
    • nonatomic property means race condition can happen when access the variable or property from multiple threads.

In general, use atomic for object shared with multiple threads and nonatomic for UI or not shared object.

Bryan Chen
  • 45,816
  • 18
  • 112
  • 143
iBhavin
  • 1,261
  • 15
  • 30
  • the 3rd point make no sense. for `atomic` property, it is kinda right? for different reason. for `nonatomic` property (which is OP asking for), they are almost same unless setter is override and no memory leak can happen (without considering race condition). – Bryan Chen Jul 31 '14 at 09:06
  • @iBhavin - Yep, `atomic` does not ensure thread-safety, especially with something like a mutable array (which is [not thread-safe](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-SW1)). The `atomic` merely assures that the pointer can't be mutated by one thread while being accessed by another, but makes no assurances about the object it points to. It's useful when dealing with fundamental data types, but has little practical utility beyond that. – Rob Aug 08 '15 at 15:48
2

Attention, you will get compiler error with your code:

@interface ViewController (){
    @property (nonatomic, strong) NSMutableArray *myArray;
}

-> you must move @property... outside of {} of your header.

@interface ViewController (){
    //
}

@property (nonatomic, strong) NSMutableArray *myArray;
Duyen-Hoa
  • 15,384
  • 5
  • 35
  • 44
1

A couple of thoughts:

  1. The first example is not syntactically correct. You probably meant the following, which defines a declared property inside the class extension:

    @interface ViewController ()
    @property (nonatomic, strong) NSMutableArray *myArray;
    @end
    

    A property will:

    • Synthesize an instance variable called _myArray (or if you specify a @synthesize directive, you can control the name of this instance variable);

    • Synthesize accessor methods, notable a myArray getter that retrieves the value and a setMyArray setter that sets the value;

    • Provide other features such as key-value coding, etc.

  2. On the other hand, the following declares a global variable:

    @implementation ViewController
    NSMutableArray *myArray;
    @end
    

    Globals are a very different beast, shared amongst all of the various instances of this class (and across the whole app). In this case (some mutable array used by a class instance), a global is likely not what you intended.

  3. If you intended to define an instance variable, you could do:

    @implementation ViewController
    {
        NSMutableArray *myArray;
    }
    @end
    

    Or, perhaps better than defining this ivar in the @implementation like that, one would generally define them within the class extension's @interface:

    @interface ViewController ()
    {
        NSMutableArray *myArray;
    }
    @end
    

I suspect you didn't actually intend to compare the global variable to a instance variable (ivar) or property, but rather were asking the rationale for privately using a property vs. ivar within a class implementation:

Bottom line, within a particular class, using ivars is a perfectly acceptable practice, but many of us use private properties defined in class extensions. The overhead is minimal and it abstracts the code away from the implementation details of the ivar. For example, you can customize one or more of the accessor methods at some future date and have minimal impact on the rest of the class implementation. But it's a matter of personal preference.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

@property creates your setters and getters the other one does not.

Kets
  • 438
  • 2
  • 8
  • 24
  • and this is the only difference? why should I use setters and getters in class which contains those variables? – Roval Jul 31 '14 at 08:40
  • property is useful, when you want to transfer value between two viewcontrollers – Indrajeet Jul 31 '14 at 08:42
  • yes I know, but when I want to transfer values between controllers I put them in .h file not in .m file – Roval Jul 31 '14 at 08:44
0

yes, @property is automatically creates setter and getter.

additionally, you can setting property's attribute. (read-only/readwrite, nonatomic/atomic, strong/weak.. etc)

accessing instance variable by getter & setter(instead of using pointer to direct access) make data encapsulated.

it is common and important concepts of Object-Oriented Programming.

read this for understanding.

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

sorry for poor english. :<

Luvie
  • 126
  • 7