Few Quick Questions About iOS Programming in Xcode - iphone

1) For the interface .h file, should I import classes (#import "Person.h") or should I use #class (#class Person)? And I should always use import in the .m, right?
2) Can I get rid of the following methods if I don't use autorotate?
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
3) Do I need to separate IVariables from properties when declaring them in the interface? I see both ways being done.
Edit:
What about these methods?
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}

#class is usually enough in your header file. See this question.
All of those methods are performing their default behaviors, so you can remove them regardless of whether you use autorotation. You would want to keep them if you need to add additional behavior. (Using super means to call the superclass implementation — i.e., the implementation that would be used if you hadn't defined this method. So if you are only calling super and not doing anything else, there's no point.)
It's fine to leave them out, but I think this only works after iOS 4. See this question.

You can use #class for types, but if your class subclasses something you need to import the latter. Likewise for protocols. You will probably need to import the class, e.g. #import "Person.h", at the top of the implementation file. A good rule I can offer: If the compiler chokes here, import!
Yes. As jtbandes points out, the call goes through to super which has a default implementation.
You don't need the iVar declarations if there's a property to go with them, I do without because I don't want to clutter my interface. I think this works since Objective-C 2.0, not since iOS4.0. (I've used this on iOS3.0 for example). Also, omitting iVars helps prevent zombies and maintain the correct retain count - it encourages you to use the right setter. But some times it's good to use iVars with no property and a "#private" declaration if your object needs to store some data but you don't want to expose it. An example I often come across is UITableViewController, which might hold an array to populate it's rows.

Related

Releasing ivars in Objective-C

OK, looking at this:
Apple docs: Declared Properties
If you scroll down to dealloc it reads:
"Typically in a dealloc method you should release object instance variables directly (rather than invoking a set accessor and passing nil as the parameter), as illustrated in this example:"
- (void)dealloc {
[property release];
[super dealloc];
}
"If you are using the modern runtime and synthesizing the instance variable, however, you cannot access the instance variable directly, so you must invoke the accessor method:"
- (void)dealloc {
[self setProperty:nil];
[super dealloc];
}
Now, I must own at least 15 to 20 books on iOS development. I can't say that I have ever seen any code in these books proposing that one do anything other than:
[someproperty release];
Is there a compelling reason to edit a bunch of files of code that works perfectly well to adopt Apple's recommendation? How about future work? Or, are they pretty much equivalent?
Apple's document appears to apply only if you have synthesize-by-default turned on. If you have it turned off, which seems to be the default case, you need #synthesize, which gives you access to variables directly.
Personally, I do:
#synthesize someProperty=_someProperty;
just so I can then do:
- (void)dealloc {
[_someProperty release];
[super dealloc];
}
See Jeff LaMarche's blog for more.
On the modern runtime, you no longer have to declare instance variables for properties, nor do you have to write #synthesize in the implementation. If your code already has the instance variables declared, then there's no reason to replace code that calls release with a call to a set accessor (the first quote you pasted even states that).

Question about inheritance

What code is correct and why ?
- (void)viewDidLoad
{
/*my code
*/
[super viewDidLoad];
}
or
- (void)viewDidLoad
{
[super viewDidLoad];
/*my code
*/
}
It doesn't really matter that much. It's more about the way you'd like it. Would you want the super to respond first or the self? If it doesn't really matter that hard, do what you like.
It depends on whether you want your subclasses code to execute before or after the superclasses code for that method. I would say it's more common to do your own custom code after the call to super so that your subclasses code follows the superclasses code. Again, it depends on exactly what your trying to do.
I'd say the latter. You want your superclass's code to run first before you run your own.
Or, if you're completely replacing the function, you'd just comment out the call to the superclass's implementation.

Where to initialize custom UIView, instantiated in Interface Builder?

I have a subclass of UIView that's instantiated in a XIB file. I need it to do some initialization (settings some variables and creating a subview).
However, I do not always instantiate this view via Interface Builder. I do it programmatically too. In both cases, the initialization needs to be the same.
My designated initializer is initWithValues:.
The question is; where do I perform the initialization?
Since I have to perform it in 2 different locations, I figured I need to refactor it in a separate initialize method (or something like that), and call it from initWithValues:.
But when loading from IB, both initWithCoder: and awakeFromNib are called. From which method do I have to call initialize? Or do I have to call initWithValues: from initWithCoder: and do nothing in awakeFromNib?
You should use initWithFrame: when initializing views (since it's the designated initializer). Hence, if you have initWithValues: make sure you call initWithFrame: from it.
Something like this should work for initializing: ;)
- (void)initialize{
//init your ivars here
}
- (id)initWithCoder:(NSCoder *)aCoder{
if(self = [super initWithCoder:aCoder]){
[self initialize];
}
return self;
}
- (id)initWithFrame:(CGRect)rect{
if(self = [super initWithFrame:rect]){
[self initialize];
}
return self;
}
I was going to add a further explanation, but mplappert's answer is clear enough. Use awakeFromNib if necessary.
That depends on what you need to initialize. As soon as awakeFromNib gets called, all outlets and action connections of your view are established which is not the case in initWithCoder:. So if you need to rely on those connections, use awakeFromNib. Otherwise you can safely do all your initializing in initWithCoder:.
Unfortunately, the above answers don't take into account these things:
- (void) awakeAfterUsingCoder - and the fact it's called after anything is created by the coder (once for every Xib view).
awakeFromNib suffers from the same fate, I've noticed. (The reason I found this)
Another initializing issue is that initWithCoder and initWithFrame can be avoided for custom views. And if they are called, lazy loading (though not as important on views themselves), means you "might" be able to modify values. I believe I've done so in initWithCoder, but if you then initialize values in awakeFromNib, it's undone at least once.
I've gone so far as to:
- (void) awakeFromNib (or didMoveToSuperView);
{
BOOL called = NO;
if(!called)
{
called = YES;
}
}
Another method I use is to simply call the initializer needed, then call my own class or superclass-specific initializer.
I, too, am looking for a dependable one-time place I can rely on. Until then, I hope my headaches save the next person an hour or so.
Steve

How do I call - (void) viewDidAppear:(BOOL)animated from another method?

It is possible to call one method from inside another. I've implemented this function
- (void)pickAndDecodeFromSource:(UIImagePickerControllerSourceType) sourceType
I want to call following method inside the above one.
- (void) viewDidAppear:(BOOL)animated
I think I understand what you're asking... the question is.. well not there. Nonetheless:
What I think you're asking: "How do I call viewDidAppear from within another method...?"
- (void)pickAndDecodeFromSource:(UIImagePickerControllerSourceType)sourceType
{
...
[myController viewDidAppear:YES]; //Simply call it on whatever instance of a controller you have
...
}
If the question was actually "How do I override viewDidAppear?" then this is it:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//YOUR STUFF
//GOES HERE
}
You can always call the delegate methods directly:
[self viewDidAppear:YES]
Called from inside your method should work.
I'm not sure exactly what you mean, but from the nature of your question I am guessing you are new to Obj-C so I strongly suggest reading Introduction to The Objective-C Programming Language if you have not already. If you have, great! What you are looking for is most likely under Objects Classes and Messaging - Object Messaging - Message Syntax

Best practice in cleaning up memory for iPhone apps?

I have seen sample source code around that uses different ways of releasing/dealloc'ing objects, so I was wondering which way is deemed the "best" one. A few options on -dealloc:
1) Release objects
- (void)dealloc {
[obj1 release];
[obj2 release];
[super dealloc];
}
2) Set objects to nil
- (void)dealloc {
self.obj1 = nil;
self.obj2 = nil;
[super dealloc];
}
3) De-allocate objects directly
- (void)dealloc {
[obj1 dealloc];
[obj2 dealloc];
[super dealloc];
}
Which way is the best one? Pros and cons for each?
Method 1 is the only recommended method. It's also good practice to set them to nil AFTER you've released them.
Method 2 only works for properties that manage their own object/value retaining, so it's not universally applicable. And if you implement your own setter method that performs other actions when the property changes, you may get undesired side effects by calling it in [dealloc].
Method 3 violates the reference-counting principle because it will deallocate the objects even if something else has a [retain] hold on them, so when the other objects access them next, your program will crash. You're never supposed to call [dealloc] directly -- let the runtime call it when the last owner calls [release].
If obj1 and obj2 are properties using #synthesize-d accessors, then method 1 and method 2 are equivalent. If either of those two conditions is not true then the effect is rather different. If they're not properties, then method 2 just sets the pointers to nil without doing anything that would deallocate the objects. And if they are properties but you've implemented your own setter methods, method 2 calls those methods with "nil" as the argument. Whether that's equivalent to method 1 or not depends on how you've implemented those methods. If your custom setters do anything significant when the argument is nil, method 2 would ensure that this code executed.
As Marco said, method 3 is just plain wrong. If you've seen sample code doing that then the author may not actually know what they're doing.