5

I am puzzled by how is variable declared in objective C.

1: I see @property and @synthesize statement being used. My question regarding that is, what are these 2 statement for? Why are they always used together? I guess @synthesize is a shortcut to create the getter and setter?

2:Say, I want to declare an NSMutableArray that would be only be accessible inside the class that was declared in. I have to perform myArray = [[NSMutableArray alloc] init] before using the addObject method to write something to it. When do I release the array then?

3:Is there a different way to declaring a variable that is only accessible only at the class it was declared to being accessible at all classes?

4:Similar to question 2, but now the variable is an NSString. Why I don't have to alloc & init it to share the same variable within its own class? Whats the different between self.myString = @""; to myString = @"";

Thanks a lot.

John
  • 71
  • 2
  • 6
  • As you get into objective-c, you might want to look at the Stanford courses (iTunes). It helped me get up the learning curve. – nykash Aug 31 '11 at 01:18
  • This is a very broad question covering ground that is well-trod here on SO. Please take a look around. Here are four previous posts that address your questions. 1: [What's the difference between @property and @synthesize?](http://stackoverflow.com/questions/806379/) 2: [When to release an instance variable](http://stackoverflow.com/questions/4063905/) 3: [How to declare instance variables not visible outside the instance?](http://stackoverflow.com/questions/5826345/) 4: [Difference between self.var vs. var](http://stackoverflow.com/questions/4627646/) There are others on each of these topics. – jscs Aug 31 '11 at 01:37

4 Answers4

5

For your first question:

@property (nonatomic, retain) NSString * someProperty;

This declares a property of the class. It becomes part of the public contract of the class but still lacks something important - actual implementation

@synthesize someProperty;

This is compiler sugar, its creates a getter and setter method for your property. To wit, this is the implementation that is needed in order to actually use your property in your class and from other classes.

You will in almost all situations, always have a @synthesize for each @property you declare.


For your second question:

You are correct about how to initialize your array property. In order to release it you would do the following in your classes dealloc method:

- (void) dealloc {
    self.myarray = nil;

    [super dealloc];
}

This effectively releases the array (assuming you declared your property with the keyword retain).


And for your last question:

Properties of a class are always available from other classes. In order to create a globally accessible variable you would declare it as static.

Perception
  • 79,279
  • 19
  • 185
  • 195
  • You might not have a `@synthesize` for every property. It can also be `@dynamic`, or you can simply declare an ivar and implement the correctly-named methods. – jscs Aug 31 '11 at 01:31
  • I agree with your first point, but your second point is unrelated to @property and more related to KVC. Edited my answer to reflect. – Perception Aug 31 '11 at 02:16
  • 1
    @Josh: indeed. In one of the other comments, I gave a few examples where you write our own accessors and don't even have an ivar, since the accessors can rely on other means (direct file access, a port, a database, an algorithm, etc.) than to get or set an ivar directly. In such cases, you don't synthesize. – Rudy Velthuis Aug 31 '11 at 02:17
  • @Perception: The second point is important for properties too because the compiler by default translates `self.ivar = obj;` into `[self setIvar:obj];` and `[obj doSomething:self.ivar];` into `[obj doSomething:[self ivar]]`. You can tell to use other method names, of course: `@property (getter=bananas, setter=setRutabegas, copy) NSString * apples;`, but you still have to name the methods however you promised when you declared the property. – jscs Aug 31 '11 at 04:37
  • Right, if you create methods with the same name as would have been synthesized by the compiler then you are ok. This is not a recommended approach though unless you know exactly why you are avoiding @synthesize in the first place. – Perception Aug 31 '11 at 12:51
2

Ad 1: a property is a construct to control access an ivar (usually private) by getters and setters. Actually, a property doesn't even have to have a supporting ivar. Yes, @synthesize generates getter and setter (and ivar).

Ad 2: You release it when you don't need it anymore. When that is depends on the logic of your code.

Ad 3: If I understand that correcttly, you want @private ivars. Normally, ivars are protected, i.e. only accessible inside the class or in derived classes. Private ivars are only accessible inside the class itself. Properties are publicly accessible.

Ad 4: myString = @"" writes to the ivar directly, while self.myString = @"" uses the property setter.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
  • I chanced about an occasion whereby I couldn't read back the ivar inside the class. I was using `ivar = something` then. Changing it to `self.ivar = something` solved the problem. Could you share some insights to what happened? I guess the ivar got auto released as I was reading back NULL. If it helps, the ivar was CLLocation. I didn't have to perform `self` for `NSString` ivars. – John Aug 31 '11 at 01:09
  • Properties, if declared as (copy) or (retain), will retain the item (and release a previous item), while directly accessing the ivar does nothing of the kind. Properties help you perform memory management, as the compiler will generate code that properly retains and releases items. They must still be released in dealloc, of course. So try to use properties everywhere, except perhaps in init and dealloc. – Rudy Velthuis Aug 31 '11 at 02:04
0

1) @property declares a publicly accessible variable and associated getter and setter. @synthesize causes the compiler to automatically generate the definition (code) of the getter and setter.

2) You would declare the NSMutableArray in your class declaration, in the header file. You would initialize the variable in your init method, and you would release the variable in your dealloc method.

3) The variables created using @property are public. The variables defined in your class declaration (using @interface in the header file) can be declared as private to that class, using the @private keyword.

John, these questions are pretty basic. You would probably get a lot out of the Objective-C Programming Intro here ( http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html#//apple_ref/doc/uid/TP30001163 ).

Mike Hay
  • 2,828
  • 21
  • 26
  • `@property` doesn't declare a publicly accessible _variable_. The ivar itself (if synthesized) is `@protected`. What it declares is an access point for some aspect of the class. There doesn't actually even have to be a variable backing it, as long as you fulfill the contract of having a getter and setter method (or just getter, in the case of `readonly`). – jscs Aug 31 '11 at 01:25
  • 1
    FWIW, if you write your own getter and/or setter, a property doesn't even have to have an ivar. It can just as well calculate something, or convert from one item to another. E.g. an Angle class could just as well have a property degrees as a property radians. Only property radians has a backing ivar, but property degrees (through the setter and getter, `degrees` and `setDegrees:`, respectively) converts to and from radians, depending on the direction. A File class can have a fullName property that uses server, directory and file name to generate or parse a fully qualified name. – Rudy Velthuis Aug 31 '11 at 02:09
0

You need to get a text on Objective-C or find an online tutorial -- it's a sufficiently arcane language that you can't hope to pick it up in dribs and drabs.

There are variables and there are properties -- two different things that intersect somewhat.

You can declare plain old instance variables the same way as in C/C++, more or less:

NSArray* myArray;

eg, placed in the {} enclosed section of the @interface.

But you can also have a PROPERTY, which you declare by saying @property in the @interface declaration (after the closing }). A property has a getter method -- by default called myProperty -- and a putter method -- by default called setMyProperty. If myProperty is the same name as one of your instance variables then you can use @synthesize to automatically create these methods.

Note that properties may be automatically retained when the default setter method is used. This is fairly convenient in terms of managing storage.

But managing storage is a big topic, one that you MUST read some good tutorial on -- we can't explain it in a few paragraphs.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151