Since, ARC is now a standard for many years do I have to write code like this:
#property (nonatomic, retain) NSString *title;
#property (copy) NSString *subtitle;
Or just simplify it to this?
#property NSString *title;
#property NSString *subtitle;
You asked:
Do I have to specify memory management properties with ARC?
In short, if you want anything other than the default behavior, yes you do. The default behavior is atomic and strong. If you want copy behavior, for example, then you must specify copy. If you want non-atomic behavior, then you must specify nonatomic.
So, let us consider the two title renditions:
#property (nonatomic, retain) NSString *title; // nonatomic
#property NSString *title; // defaults to atomic, strong
The two are different insofar as the first is nonatomic and the latter is atomic. Also, the first explicitly uses retain, which in ARC achieves the same behavior as strong. That having been said, we prefer to use strong (instead of retain) in ARC because we now reason about the reference types, not reference counts.
If you really wanted to simplify that first example, you could remove retain and rely on the fact that object properties default to strong, by default.
#property (nonatomic) NSString *title; // strong (by default), nonatomic
And you would only remove nonatomic if you really wanted to introduce the overhead of atomic accessor methods.
Consider these two:
#property (copy) NSString *subtitle; // copy semantics
#property NSString *subtitle; // strong reference only
These two are different that the former employs copy semantics (providing critical protection against NSMutableString references changing behind its back) and the latter does not.
ARC has default property params.
the following 2 property definitions are the same.
#property NSArray *name;
#property (strong, atomic, readwrite) NSArray *name;
Related
I want to show you an example of one of my header files and get your suggestions on what I could do better giving the situations below.
ARC is enabled
#property (nonatomic, assign) int some_simple_value;
#property (nonatomic, strong) NSMutableArray *someArray;
#property (nonatomic, weak) IBOutlet UIButton *someButton;
#property (nonatomic, copy) NSMutableArray *someArrayCopy
#property BOOL some_bool;
I understand what a lot of the types mean, but I don't know why I would use a given one instead of another in some cases. Also, if I know my object is only accessed by one class, should I not use nonatomic (because there's no worry of multiple threads accessing it, right?)
ANSWER
These answers helped me drastically:
What's the difference between the atomic and nonatomic attributes?
and
Objective-C declared #property attributes (nonatomic, copy, strong, weak)
Well, you could read the documentation! :) But if you want a perhaps more friendly instructive explanation, I've written you one:
http://www.apeth.com/iOSBook/ch12.html#_properties_2
However, before you read that, you should really read about memory management, earlier in that chapter:
http://www.apeth.com/iOSBook/ch12.html#_memory_management
strong and weak are very different indeed; if you understand memory management and ARC, you'll know why.
What is the difference between
#property (nonatomic, retain) NSString *subject, *name, *kind;
and
#property (nonatomic, retain) NSString *subject;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *kind;
I think the functionality is exactly the same but the first one only saves you typing and some lines of code. I am not sure though that is why I am asking :)
#property (nonatomic, retain) NSString *valtOnder, *name, *soort;
and
#property (nonatomic, retain) NSString *valtOnder;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *soort;
Both the way are same.
But I prefer later one. Reason??
If you have any typo or whatever bug, you will be pointed by compiler in exact the line having that property/variable name.
If I write dozens of property and/or variable then I have to look for each of them, which one is root cause for error.... As I used #synthesize for quite a time, it was too difficult to find.
So I always advised and guided others to make one line declaration of variables, properties, synthesize etc.
I am lazy. Few think why to write same thing multiple times? Extra time and work.
But multiple lines will be more readable. You code just once and it is read hundreds of times, so just few seconds to type some extra keywords. And thanks to all the IDEs that provide you autocomplete so nowadays this reason is nearly obsolete.
EDIT:
As per vikingosegundo comment,
you should never use retain for NSString, use copy.
For Immutable objects copy should be used not retain.
If I have a read-only string property, is it necessary to specify strong (or retain) or copy in the declaration? If I don't specify, is one of them assumed?
It seems to me the ownership attribute is only useful when you have a setter.
#property (nonatomic, readonly) NSString *name;
That is mostly correct. For a readonly property, strong, retain, weak, and assign have no effect. But if you also declare the property elsewhere as readwrite (most frequently in an anonymous category in the .m), then the other modifiers need to match.
I'm having some trouble understanding something. I got a bunch of propeties in my app:
#property (nonatomic, retain) AVAudioPlayer *audioPlayer;
#property (readwrite) NSInteger buttonCount;
#property (nonatomic, retain) NSString *soundSelected;
#property (readwrite) float fadeDecrease;
#property (readwrite) float fadeDelay;
These are obviously all synthesized in my .m file.
However, while audioPlayer and soundSelected are released fine in dealloc, the int buttonCount gives this warning:
"Invalid receiver type 'NSInteger'"
and the floats actually make the compiler cry with:
"Cannot convert to a pointer type"
Has this got something to do with the fact that they are not of object types and/or not retained?
Is it OK that they are not released?
Thanks.
NSInteger, like float, are not Objective-C types and do not follow the usual retain/release model. They're just primitives. Assigning values to the property will be sufficient.
#property (readwrite, assign) NSInteger buttonCount;
should be all you need.
NSNumber however does follow the usual retain/release cycle, so add attributes accordingly.
Has this got something to do with the
fact that they are not of object types
and/or not retained? Is it OK that they are not released?
Yes. You can only release objects that have a retain count. Primitive datatypes like int, float, and NSInteger do not need to be retained/released because they are not pointers referring to other parts of memory.
If you want to learn more about memory management, try taking a look at this documentation page:
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html%23//apple_ref/doc/uid/10000011-SW1
XCode accepts it. But will retain be applied when I internally set the property (no setter outside since readonly but when I initialize the value in a class method) ?
Regards,
Apple92
You might specify (readonly, retain) for a publicly-facing property, and then inside your .m, re-define it as (readwrite, retain) to be able to assign to it privately. I use this pattern myself occasionally.
The reason to do this is to allow you to do #property (retain) in a class continuation or category. If you don't have the retain on the outer property, you will get a warning about the properties being mismatched.
it's also nice as a form of interface documentation