In most of the tutorials I've been reading there are examples of classes with custom init methods.
For example
@implementation MyPerson
-(id) initWithDefaultName {
self = [super init];
if (self) {
NSString *name = [[NSString alloc] initWithString:@"John Doe"];
}
return self;
}
Now, I know that I am supposed to pair this up with
-(void) dealloc
{
[name release];
[super dealloc];
}
What I do开发者_如何转开发n't understand however, is why this wouldn't crash if I call [MyPerson init]
followed by [MyPerson release]
EDIT: Reading the comments below, I realised the example code above wasn't quite correct. What I'm getting at is that my custom initWithName
method allocates and initializes an object that wouldn't exist if the standard init
method was called. So my dealloc
method contains code to release it, but this still works even if the name object was never created?
Instance variables have a default value of nil
. Sending a message to nil
has no effect.
In Java if you did this:
Foo foo = null;
int bar foo.getBar();
You would get an null pointer exception. In Objective-C it is perfectly ok to send messages to nil
, it is treated as a no-op, nothing is done.
With a small caveat; methods with return types that has a size fits the ABI's default return conventions will yield a return value equal to the data-types representation of nil
. So this will all work and yield expected return values:
Foo* foo = nil;
id a = [foo objectValue]; // a will be nil
BOOL b = [foo boolValue]; // b will be NO
int c = [foo intValue]; // c will be 0
float d = [foo floatValue]; // d will be 0.0f
This can have great benefits to your code, imagine this example:
if ([myString length] > 0) {
// Do stuff here
}
In this way it does not matter if myString
is an empty string, or just nil
. Asking for the length will return 0
in both cases. Making many operations simpler to write since the nil
value seldom has to be accounted for.
Only for return types such as structs that does not fit in a return register will you not get a defined return value:
Foo* foo = nil;
CGRect a = [foo rectValue]; // content of a will be undefined.
You can safely send release to nil. Note that you should be retaining name when you assign it in your init, though.
You can send anything to a nil
object and it will just be fine.
That's why most of the tutorials also set every property back to nil
in their viewDidUnload
method.
精彩评论