Are objects in Objective-C ever created on the stack?
Asked Answered
A

2

2

As far as I understand, in C++ you can create objects on the stack:

SomeClass object = SomeClass();

or on the heap:

SomeClass *object = new SomeClass();

In Objective-C you always seem to create objects on the heap, as [SomeClass alloc] returns a pointer to a new instance. Is this correct?

Are objects ever allocated on the stack? If so, what would be a good example? Else, why not?

Arietta answered 18/12, 2013 at 16:29 Comment(1)
What about int x=0; ?(Objective C)Bluh
S
4

The short answer is that objects are always allocated on the heap, not on the stack.

This isn't quite the whole story though. In Objective-C, blocks are also full Objective-C objects. They're peculiar in that they are sometimes on the stack. In particular, blocks created with the block literal syntax, and which reference surrounding scope, are on the stack. You can even see this if you inspect their class, which will be (the private) NSStackBlock. If you copy them, with Block_copy() or -copy, the resultant copy will be on the heap (NSMallocBlock).

One implication of this is that stack-allocated blocks are only valid until the end of the scope in which they were created. Prior to ARC (and IIRC in early version of ARC as well), this meant that you had to copy blocks that you wanted to live past their creation scope so they'd be on the heap. ARC handles this for you in most cases now, and also means that whether a block is on the stack or the heap is harder to predict.

This small test program shows this (compile with ARC off):

#import <Foundation/Foundation.h>

// Compile this without ARC.

int main(int argc, char *argv[]) {
    @autoreleasepool {

        NSMutableString *string = [NSMutableString stringWithString:@"foo"];
        void(^stackBlock)() = ^{
            [string setString:@"bar"];
        };
        NSLog(@"stackBlock class: %@", NSStringFromClass([stackBlock class]));

        void(^heapBlock)() = [[stackBlock copy] autorelease];
        NSLog(@"heapBlock class: %@", NSStringFromClass([heapBlock class]));
    }
}

Output:

stackBlock class: __NSStackBlock__
heapBlock class: __NSMallocBlock__

(Just to be clear, you certainly shouldn't use a check for NSStackBlock/NSMallocBlock in real code. They're private implementation detail classes. This code is just for demonstration.)

Solitta answered 18/12, 2013 at 17:25 Comment(0)
C
3

Basic primitive types (int, float, and double) will be created on the stack.

The actual pointer (i.e. the object in SomeClass* object) is created on the stack even though it points to an object on the heap.

You are correct in saying that anything created with a new is created on the heap.

Capitulum answered 18/12, 2013 at 16:32 Comment(3)
I'm aware of primitives and pointers. But actual objects are never placed on the stack then, i.e. you couldn't do it even if you wanted to?Arietta
No they are not as all objects are created with new.Capitulum
What do you mean with "all objects are created with new"? In Objective-C? Don't you mean alloc? As far as know, new in Objective-C is just a shortcut for alloc/init.Arietta

© 2022 - 2024 — McMap. All rights reserved.