UIButton - alloc initWithFrame: vs. buttonWithType:
Given (arbitrarily):
CGRect frame = CGRectMake(0.0f, 0.0f, 100.0f, 30.0f);
What's the difference between the following two code snippets?
1.
UIButton 开发者_StackOverflow中文版*button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = frame;
2.
UIButton *button = [[[UIButton alloc] initWithFrame:frame] autorelease];
I think they're equivalent. Haha! Trick question you sneaky little punk!
Reasoning
-buttonWithType:
returns an autoreleasedUIButton
object.+[NSObject alloc]
defaults scalar instance variables to0
, sobuttonType
should be0
, orUIButtonTypeCustom
.
Pros & Cons
You could argue that it's clearer to use
-buttonWithType:
and setbuttonType
explicitly and that it's safer in case Apple changesUIButtonTypeCustom
to be1
instead of0
(which will most certainly never happen).On the other hand, you could also argue that it's clear & safe enough to use
-initWithFrame
. Plus, many of the Xcode sample projects, such as "TheElements" & "BubbleLevel," use this approach. One advantage is that you can explicitly release theUIButton
before the run loop for your application's main thread has drained its autorelease pool. And, that's why I prefer option 2.
I would strongly suggest using the first approach (+buttonWithType
), because that's the only way to specify the button type.
If you +alloc
and -initWithFrame:
, the buttonType
is set to some standard value (not sure which, and this could change in later versions of the SDK) and you can't change the type afterwards because the buttonType
property is read only.
The main (maybe the only) difference is in memory management: as you said, buttonWithType
returns an autoreleased UIButton
. This way you don't have to worry about releasing it. On the other hand, you don't own it, so you cannot release it when you want to (except, of course, if you drain
the autorelease pool).
Calling explicitly [[UIButton alloc] initWithFrame:frame]
, instead, you dynamically alloc your button, so you own it and you're responsible for releasing it.
If you plan to retain your button for some reason then maybe you should consider the second solution, but if, as in this case, you are autoreleasing it immediately, there's no big difference between the two way of creating a button...
Two options are the same but I prefer option 2 because it can handle memory management
You can use the first and do "[button retain];", so you will never lose the pointer.
I've went through the UIButton
documentation, and here what i've found:
Discussion This method is a convenience constructor for creating button objects with specific configurations. If you subclass UIButton, this method does not return an instance of your subclass. If you want to create an instance of a specific subclass, you must alloc/init the button directly.
I guess this is the trick. The alloc-initWithFrame
is for subclasses.
精彩评论