Objective-C property - iphone

I'm developing an Iphone app. I read from a book about declaring a property like below:
#property (nonatomic, retain) NSArray *listData;
Then in the implementation file, dealloc method, must put something like:
[listData release];
I wonder if I declare as
#property NSArray *listData;
do I have to release it? It'll save 1 line of code for me.

Yes, you have to release it. The retain qualifier means that when you set the property, your class will call retain on the NSArray. When your class is done, you need to release anything that you have retained, otherwise you have a memory leak.

#property NSArray *listData;
will just implicitly declare your accessor and mutator methods for listData,
but what about memory management(it's a serious stuff as far as iphone app development is concerned)?
If you going to use it in implementation then you should release it in dealloc method
also refer Official Apple docs for #property

Related

Need to release IBOutlet object?

I have dilemma about Memory releasing IBOutlet object.Do anyone please suggest what to do when we create IBOutlet object without property, need to release it?? if need to release... why we are releasing it
The answer is YES.
The runtime connects the objects to IBOutlet using [setValue:ForKey:]. This function will find the private instance variables, retain the target and set it to the instance variable. Please visit here iOS Developer Library to know more.
I highly recommend you to read the article because many iOS framework accesses properties by Key-Value compliance ([setValue:ForKey:] or [valueForKey:]), instead of directly calling getters/setters/instance variables.
IBOutlet does not change the ownership semantics of properties. If you do not use ARC you have to release retained objects as with any other property.
Just Set it to default, which is "Weak". Then you are fine with ARC.
Why not just have a private IBOutlet property, to make things clearer and more explicit. I always do this personally:
MyClassName.m
#interface MyClassName ()
#property (nonatomic, weak) IBOutlet NSObject *myPropertyNameForAnOutlet;
#end
#implementation MyClassName
...
#end
You are not the owner of that object. so no need to release IBOutlet object.If you are using #property (nonatomic, retain) on IBoutlet object then you must release that object in dealloc.
Take a look at Advanced Memory Management Programming Guide
You must not relinquish ownership of an object you do not own
Answer is YES...
i was confused about that too, but try this:
open a xib file
onen assistant editor window and get the .h file code near your XIB IB file
chose an object in IB file (an object with no reference to any var)
ctrl click on it and chose: "new reference outlet" button
drag the line to your .h code file in the #interface{ } section
give a name to your new var ("aaa")
(note that no property "aaa" is created)
now Xcode has done all the magic for you, and...
in .m file you can find, in dealloc method:
- (void) dealloc {
[aaa release];
[super dealloc];
}
so... if apple release it, it seems that the default IBOutlet vars loaded via XIB file are retained...
EDIT:
here's the point in apple doc:
You are not the owner of the object, therefore you do not release it.
You become the owner by retaining, copying or creating (init/alloc) an object. Only then you are you (one of the) owner(s) of the object, and need to release it when you are done with the object. Fore more info check
Cocoa core competencies - Memory Management
I hope this explains why you do not have to release the object.
Even though you didn't set it as property, the property is refer to setter and getter methods. When you use an object you should always remember to release it. The property is unrelated with memory issue.

How to release IBOutlet defined as property?

sorry for this question, but I searched it and I didn't find an answer for that case.
I'm studying memory management for iOS and I understood, or I think so, the view lifecycle. But now I have a question on a IBOutlet (tat is linked to a UIImageView in my xib file).
I have a class like this:
#interface MyClass : UIViewController
#property (nonatomic, retain) IBOutlet UIImageView *myImage;
The question is: how can I release myImage? Is this ok?
- (void)dealloc {
self.myImage = nil;
[super dealloc];
}
- (void)viewDidUnload {
[super viewDidUnload];
self.myImage = nil;
}
Can someone explain why can't I call the release method on myView (if you had some lik it is good too!)?
Thanks in advance!
IBOutlet have nothing to deal with memory management.
But because it is retain property, so you need to release it in dealloc.
So your code is correct.
In general, you don't call release on a property, you would call it on the corresponding ivar. This is my standard way to handle IBOutlet properties:
#interface MyClass
#property (nonatomic, retain) IBOutlet UIImageView *myImageView;
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
#end
#implementation MyClass
#synthesize myImageView = _myImageView;
#synthesize myLabel = _myLabel;
- (void)dealloc {
[_myImageView release];
[_myLabel release];
[super dealloc];
}
#end
What you are doing is correct, and you generally shoudnt call release on the properties, since setting to nil does that already, however if you have a backing ivar to your property you can call release on that...
There's a property and an instance variable behind the property. They both are called myImage, I presume (or you wouldn't be asking this question). You can free the instance in two ways - either release and nil the ivar, or just nil the property.
The compiler-generated setter for retained properties (like this one) works as following: release the currently held object reference (if any), assign the new value to the underlying ivar, retain it (if not nil). So when you assign nil to a property, it has the effect of releasing the current value and replacing it with nil.
To do that, use
self.myImage = nil; //invoke property setter behind the scenes
To free an ivar, use
[myImage release];
myImage = nil;
This is functionally equivalent to the code above. Marginally faster. The thing you should be clear about is the distinction between properties and backing ivars. For that very reason, some people make a point of assigning different names to them, and synthesizing like this:
#synthesize MyImage = _MyImage;
From Apple's documentation:
Legacy Patterns Prior to ARC, the rules for managing nib objects are
different from those described above. How you manage the objects
depends on the platform and on the memory model in use. Whichever
platform you develop for, you should define outlets using the
Objective-C declared properties feature.
The general form of the declaration should be:
#property (attributes) IBOutlet UserInterfaceElementClass *anOutlet;
Because the behavior of outlets depends on the platform, the actual declaration differs:
For iOS, you should use:
#property (nonatomic, retain) IBOutlet UserInterfaceElementClass *anOutlet;
For OS X, you should use:
#property (assign) IBOutlet UserInterfaceElementClass *anOutlet;
You should then either synthesize the corresponding accessor methods,
or implement them according to the declaration, and (in iOS) release
the corresponding variable in dealloc.
This pattern also works if you use the modern runtime and synthesize
the instance variables, so it remains consistent across all
situations.
First of all: consider switching to ARC if you aren't supporting iOS versions prior to 4.0.
Secondly, the best practice of writing dealloc methods says not to invoke setters. Instead, expressly release and nil your outlets:
[myImage release], myImage = nil;
Finally, when chaining together de-initialization methods like viewDidUnload, always call super's implementation after you do your own work.
The reason we nil out outlets in viewDidUnload is because sometimes views are unloaded when the system is under memory pressure. Since these outlets can be recreated easily, implementing viewDidUnload is a way to help performance, and in extreme situations, prevent your app from being forcefully terminated.
The reason we release properties in dealloc is to prevent memory leaks. So even though these two methods can look quite similar, they serve somewhat different purposes.
I don't really get what you mean by "why can't I call the release method on myView"
Your code seems correct to me but by convention I usually prefer to release the iVar directly for a retained property
I usually synthesize my property like this :
#synthesize myImage = _myImage;
And then you I release the iVar in the dealloc method
- (void)dealloc {
[_myImage release];
[super dealloc];
}
Anywhere else in the Controller I just go for the getter and setter (the dot convention)
Your viewDidUnload is correct.
By the way, if you're using ARC just declare your IBOutlet as a weak pointer. It will be automatically released in low memory situations and reloaded as soon as your view is loaded back again.
Hope this will help ;)

#synthesize IBOutlet property

I'm an Objective-C newbie and I'm reading "iPhone programming" by Alasdair Allan. While reading, I found this code:
#interface RootController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *tableView;
NSMutableArray *cities;
}
// warning: remember this tableView
#property (nonatomic, retain) IBOutlet UITableView *tableView;
The relative implementation starts this way:
#implementation RootController
#synthesize tableView;
Now: I learnt that #synthesize is a sort of shortcut to avoid boring getters and setters.
But I've some question:
in the code of the implementation tableView is never explicitly called but the dealloc releases it;
if it never gets called explicitly why the #synthesize?
Is it mandatory for IBOutlets to be synthesized?
From Memory Management of Nib Objects,
When a nib file is loaded and outlets established, the nib-loading mechanism always uses accessor methods if they are present (on both Mac OS X and iOS). Therefore, whichever platform you develop for, you should typically declare outlets using the Objective-C declared properties feature.
For iOS, you should use:
#property (nonatomic, retain) IBOutlet UIUserInterfaceElementClass *anOutlet;
You should then either synthesize the corresponding accessor methods, or implement them according to the declaration, and (in iOS) release the corresponding variable in dealloc.
in the code of the implementation tableView is never explicitly called but the dealloc releases it;
That is because when you do assign a value to the tableView, your controller retains it, and it will need to release it when it gets dealloc'd. Don't forget, #properties declared in an interface are publicly accessible. In your case specifically, the tableView you're declaring as IBOutlet is initialized by the view controller loadView method using the connections you define in Interface Builder between the File's Owner and the UITableView.
if it never gets called explicitly why the #synthesize?
You need to provide accessors for all declared #properties. They can be #synthesized, or you could write your own.
Is it mandatory for IBOutlets to be synthesized?
No, but it's way more convenient that way. The rule enforced by the compiler is that #properties must have corresponding accessors (synthesized or not) in the implementation.
For reference: From Xcode 4.4 and LLVM Compiler 4.0 on the #synthesize directive is no longer required as it will be provided by default for #properties defined in the interface.
If you type
#property (nonatomic, retain) IBOutlet UITableView *tableView;
you tell the compiler: "Listen, there will be a getter and a setter. If appropriate, use them!" And it will use them when loading the nib.
Therefore you have to implement the getter and the setter otherwise the compiler will complain.
The IBoutlet pseudo-type is just a marker so that the InterfaceBuilder "knows" that the mentioned class-file has a handle/outlet to the UITableView instance.
When compiling IBOutlet is being removed by the preprocessor (InterfaceBuilder parses (looks at) the source files). It's similar with IBAction: it is being replaced with void by the preprocessor.
That said, you could use the reference to said instance to do stuff programmatically (Like adding/changing values of the UITableView)

passing object between two views (iOS SDK)

What is the best way to pass an object between two views and how would I go about doing so?
If you are using two view controllers then making property will be best way for you.
in .h file
NSString *name;
#property (nonatomic, retain) NSString *name;
and in .m
#synthesize name;
for more how to use property look -
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW1
Use the properties declared in each controller.
I'm assuming you have two view controllers, ViewController1 and ViewController2. In both header files (.h), add an instance variable:
CustomObject *myObjectToPass;
and also
#property (nonatomic, retain) CustomObject *myObjectToPass;
If you are passing a BOOL, int or float, then do not retain it, for an NSString, use copy in place of retain, etc.
In the implementation file (.m), synthesize the variable:
#synthesize myObjectToPass;
Now you can get and set the object between viewControllers. The best way to do this depends on how they are related (e.g. in a navigationController or a tabBarContoller, etc). This should get you started, though.

Why IBOutlet retain count is 2

Why IBOutlet retain count is 2 not just 1??
and what is the difference between
IBOutlet UILabel *fooLabel;
and
UILabel *fooLabel;
#property (nonatomic, retain) IBOutlet UILabel *fooLabel;
Why IBOutlet retain count is 2 not just 1?
You don't care. No, honestly, you don't. This is precisely why people will tell you not to ever worry about retain counts. You can never guarantee that it will be any particular number you expect. Retain counts are Cocoa internal implementation details. There's no reason why it shouldn't be 100 if the framework wants it to be, or even UINT_MAX.
and what is the difference between
IBOutlet UILabel *fooLabel;
and
UILabel *fooLabel;
#property (nonatomic, retain) IBOutlet UILabel *fooLabel;
The first declares an instance variable that can act as an outlet. The second declares a property that can act as an outlet. When the NIB is loaded, in the first case the pointer is assigned directly to the instance variable and in the second, the accessor is used to assign the instance variable.
The absolute retain count value is irrelevant to your own memory management practices. Do not rely on it to diagnose memory management issues. You should check out Apple's documentation - link here
As for your second question, here's a quick overview
IBOutlet UILabel *fooLabel; declares a fooLabel variable along with an outlet for your Interface Builder nib file.
UILabel *fooLabel; as above without the outlet for Interface Builder.
#property (nonatomic, retain) IBOutlet UILabel *fooLabel; declares a property fooLabel and an outlet for your nib file. If you synthesize this property with synthesize fooLabel, it will create a getter and setter methods for the property. The (retain) attribute tells the synthesized setter method to retain your new value before releasing the old one.
1) Do not use retainCount to reason about "retain state" of object - When to use -retainCount?
2) In both cases outlet object will be retained because of KVC (in the first case it's "magic"). That means that in both cases you have to release it when you're done with it (e.g. in dealloc).
3) Second snippet is guaranteed to work as intended, while behavior of the first one looks like implementation dependent to me (I can't find clear documentation on KVC for non-property ivars).
Check your code carefully whether you are explicitly retaining the label([fooLabel retain]). If not, then don't release it twice. Release it only in dealloc.