Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Objective-C actually do when you declare an object?

I have read the memory management guide from Apple and I don't see where this case is explained...

Many times, especially when writing a class method to return an instance of a class, I'll start it out like this, because that's how I've seen it done, and it works.

[NOTE] This code is from memory - I'll update it when I get home to show an example that really works (I made this up to illustrate it, but obviously I don't recall it well enough to construct something that makes sense...

[EDIT] Here's my actual method - of course everyone was right that I must be calling alloc which I am.

+ (id)player
{
    Player *player = nil;
    if ((player = [[[super alloc] initWithFile:@"rocket.png"] autorelease])) {
    [player setProjectileType:kProjectileBullet];
        [player setProjectileLevel:1];
        [player setInvincible:YES];
        [player setEmitter:[CCParticleSystemQuad particleWithFile:@"exhaust.plist"]];
        [[player emitter] setPosition:ccp(0.0, player.contentSize.height/2)];
        [player addChild:player.emitter];
    }
    return player;
}

So what I got from the responses is: * Declaring the instance just gets me a pointer to a memory location and tells Xcode what class the object will be. * Setting the pointer to nil pretty much just sets it to zero - keeping it from having garbage in it (right?) * Since I'm autoreleasing the instance, the object that is returned is also autoreleased.

Thanks for helping me understand this!

like image 617
Steve Avatar asked Jun 10 '11 18:06

Steve


3 Answers

Can someone explain what the compiler does when it sees this?

    DooDad* aDooDad = nil;

If you are really interested in what the compiler does, the answer is: the compiler will reserve some memory on the stack for the local variable aDooDad, which is a pointer type (it is generally 64 or 32 bits in size depending on the processor). That pointer is then initialized to contain nil (usually 0x00..00).

A statement like this:

         DooDad* aDooDad = [[DooDad alloc] init...];

makes use of pointer variable aDooDad to store the address in memory of the object that is further allocated (which is the address of memory reserved by alloc).

So, in the end,

    DooDad* aDooDad = nil;

is not declaring an object, just a variable whose content is interpreted as the address of an object of DooDad type. Such declaration, therefore, is just like any other declaration you know, e.g. when initializing an int to 0, so that later you can assign it some value in an if statement.

A statement like:

 [aDooDad doSomething];

is interpreted by the Objective-C runtime system like: send message doSomething to the object whose address is stored in aDooDad. If that address is nil no message is sent. On the other hand, if you dereference a nil pointer: *aDooDad you'll get undefined behavior.

Pointers are pretty low level stuff. I hope this helps.

like image 192
sergio Avatar answered Nov 10 '22 15:11

sergio


If you're familiar with C or C++, variables can be created in one of two ways, statically on the call stack, or dynamically on the heap. Variable memory created on the stack is is reclaimed when the current stack frame goes out of scope, so you never need to worry about creating or destroying it. In Objective-C, objects are always dynamically created. Primitives (like int, float, pointers, etc), can either be statically or dynamically created. For illustration:

- (id)something {

    NSObject myObject; // Illegal static object allocation
    NSObject* myObject; // Legal primitive (pointer) static allocation
    int myInt; // Legal primitive static allocation
    int* myIntPtr; // Legal primitive (pointer) static allocation
}

So when you say DooDad* dodad = nil;, you're creating a primitive (pointer to a DooDad) on the stack. Being a stack variable, you don't alloc or dealloc it, just like you wouldn't worry about alloc'ing or dealloc'ing any of the memory in the following method:

- (id)allStackVariables {
    int myInt = 0;
    float myFloat = 0.0f;
    float* myFloatPtr = NULL;
    NSObject* myObject = nil;
}

Setting it to nil simply sets the contents of the variable to whatever the compiler defines to be nil, something like 0x000000 in hex. Saying DooDad* dooDad = nil; is conceptually identical to saying something like int myInt = 0;

like image 4
Matt Wilding Avatar answered Nov 10 '22 15:11

Matt Wilding


Declaring simple gives you a pointer you can use later. No memory is allocated.

Not sure what the intent of the method you posted, but it seems wrong on many levels. It will return nil, always. Unless it's an initializer method, it should not call [self init]. If it is an initializer method, it should return self and be named something like "init..."

like image 2
picciano Avatar answered Nov 10 '22 16:11

picciano