Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C allocating objects on the stack

I am new to Objective C and doing some practice with objects. While something like Fraction* f = [[Fraction alloc] init ]; works, whenever I try to do Fraction c; I get Interface type cannot be statically allocated Is there anyway to allocate objects on the stack (like in c++) ? or am I trying the wrong thing ?

like image 837
Cemre Mengü Avatar asked Jan 16 '23 13:01

Cemre Mengü


2 Answers

Technically, you can (see code below), but you shouldn't. Also, be it in the stack or the heap, you only have a pointer to the object, not the object itself. That is, you should write Fraction *c, not Fraction c.

// Allocate an Objective-C object on the stack.
// Original code By Graham Lee: 
// https://gist.github.com/iamleeg/5290797     

#import <Foundation/Foundation.h>
#include <stdlib.h>
#include <objc/runtime.h>

@interface A : NSObject
@property (assign) int meaning;
@end

@implementation A

- (id)init {
    if ([super init]) {
        _meaning = 42;
    }
    return self;
}

@end


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

        // allocate and zero stack memory
        size_t size = class_getInstanceSize([A class]);
        id obj = (__bridge_transfer id) alloca(size);
        memset((__bridge void*)obj, 0, size);

        // set class and initialize the object
        object_setClass(obj, [A class]);
        obj = [obj init];

        NSLog(@"meaning: %d", [obj meaning]);

        // transfer ownership from ARC to CF so ARC doesn't 
        // try to improperly free the stack allocated memory
        CFTypeRef ref = (__bridge_retained CFTypeRef) obj;
    }
}

alloca() is non standard, unsafe, non portable, and prone to stack overflows.

like image 95
Jano Avatar answered Jan 18 '23 02:01

Jano


You cannot allocate an object statically in Objective C. There are a lot of reasons for this. Including the fact that objects should be initialized but initialization methods are allowed to change the address of the object.

In C++ a constructor must initialize the object it's called upon and cannot, in any way, change the object address. This is not true in Objective C. The equivalent of constructors (the alloc+init* sequence or a class level method) are allowed to decide that they are going to change the address of the object they are called upon (they will take care of freeing the original object, of course).

There's no way for them to free the statically allocated memory nor to change the address of your stack, of course.

like image 39
Analog File Avatar answered Jan 18 '23 03:01

Analog File