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
Related
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;
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.
Whats the difference between this:
#property (nonatomic, weak) id <SubClassDelegate> delegate;
and this:
#property (nonatomic, assign) id <SubClassDelegate> delegate;
I want to use property for delegates.
The only difference between weak and assign is that if the object a weak property points to is deallocated, then the value of the weak pointer will be set to nil, so that you never run the risk of accessing garbage. If you use assign, that won't happen, so if the object gets deallocated from under you and you try to access it, you will access garbage.
For Objective-C objects, if you're in an environment where you can use weak, then you should use it.
My xcode version is 4.2.
When I use property to generate getter/setter methods.
Here is the code:
#interface NewSolutionViewController : UIViewController
#property(nonatomic, weak) NSString a;
There is no issue exist. However when I turn into basic data type
#interface NewSolutionViewController : UIViewController
#property(nonatomic, weak) int a;
My program crashed. Do you guys know the reason?
A basic data type is not an object, and hence does not need to be declared weak.
Use
#property (nonatomic, assign) int a;
to directly assign to the variable.
The problem is that an int is not an NSObject.
Elaborating a bit...
NSObject is the root class of most Objective-C class hierarchies. Read up on Apple's Objects, Classes, and Messaging tutorial.
int is a basic machine type. It doesn't have methods, like an object, so it doesn't respond to messages.
int doesn't respond to retain - you probably want to put an assign in the property declaration for that one.