Strong properties - why not assets array?


#1

I think I get the idea of strong properties, in that ARC will manage object ownership for you as long as an instance variable is declared (strong) - like the *label in Asset.h -

So why in Employee.h don’t we also declare the asset array like so:

@property (strong) NSMutableArray *assets;

and also synthesize it in the implementation:

@synthesize assets;

I tried this and it appears to work… So I’m confused, the deallocation of the arrays works without it, right?

Also, first post here, so hello everyone!

Thanks!


#2

Well hello! Welcome!

When declaring a property, ARC REQUIRES that you include a storage specifier for object pointers (such as strong, weak, or unsafe_unretained - the latter two of which you learn in the next chapter). Also, the storage specifier must match the explicit instance variable declaration’s storage specifier, if you have one. This is because of an historical quirk regarding assumptions made by @property.

Since the assumed/default storage specifier for an object pointer is strong, the storage specifier for an instance variable object pointer that you must use is strong.

I think that this will become more clear after you finish the Preventing Memory Leaks chapter. If it does not, by all means, let us know.


#3

Thanks - so I’ve “read” the next chapter, but not done the exercises, or worked the code yet, so I have a general understanding of (weak)… Are you basically saying that if no storage specifier is stated, then (strong) is assumed? Meaning you could theoretically have left it off of the NSString *label , and it would still be treated as strong as long as it’s declared as a @property, and implemented with @synthesize ?

Or is an instance variable always assumed / defaulted to strong if not declared otherwise, regardless of the use of @property, and @synthesize? In the case of the array, it was not implemented as a property, because it is used more like what I would call a private variable? (I’m a VB.Net guy by day…, don’t tell anyone…) :slight_smile:


#4

The rules are slightly different between explicit ivar declarations and property declarations.

With an explicit instance variable declaration, strong ownership is assumed:

@interface Officer : NSObject { NSString *name; // I'm a strong pointer, because __strong is the default! __strong NSString *rank; // I'm a strong pointer, also! __weak NSString *superiorOfficer; // I'm a weak pointer~ }

With a property declaration, assign is the default storage specifier, and is the only storage specifier allowed for primitive types. Assign, however, is rarely what you want for an object pointer, so the compiler will require you to provide a storage specifier for object pointer properties (but not primitive properties). This is really just to protect you from accidentally accepting assign when you don’t mean to.

[code]// I’m all good, because I’m a primitive type, and I want to be assigned, which is the default.
@property (nonatomic) float height;

// Uh oh. The compiler’s not going to like this. Primitive types can only be assigned.
@property (strong, nonatomic) int age;

// The compiler won’t like this either, because I’m an object pointer, so I need an explicit storage specifier.
@property (nonatomic) NSString *name;

// Ah, much better. I just need to make sure my specifier matches my ivar declaration’s.
@property (strong, nonatomic) NSString *rank;

// assign is okay, if that’s really what I want. I just have to be clear about it.
@property (assign, nonatomic) NSString *favoriteColor;[/code]


#5

Thanks for the help - I think I will have to come back to this once I’ve got a better overall understanding of things… I do now understand above where the __strong NSArray *assets would be the same as NSArray *assets, so that does make sense… As for nonatomic and assign, I’ll have to come back to that.

One last thing for now, so when something is declared as a @property and synthesized, is this just a shortcut to creating the (set and get) methods? In other words, since the asset array was not used in the “typical” way of accessing it directly through a get or set method, but rather “internally”, then it didn’t need to be declared as a property? I guess what I’m asking is: all instance variables do not have to be declared as properties, right?


#6

Correct. A property declaration is merely shorthand for an accessor (setter/getter) declaration. Just as you aren’t required to implement accessors for your ivars, you’re not required to declare them as properties.

When you declare an @property, you’re telling the compiler, “When I say GO, write a getter and setter for me using the rules that I’ll itemize inside these parentheses.”

Then, when you type @synthesize, you’re telling the compiler, “GO!”. The compiler stops right there and writes your getter and setter for you in that very spot, following the rules you indicated with the keywords in the parentheses of your @property declaration.

This way, you can reduce roughly 8+/- lines of code for your accessors to just two.