Objective C在堆栈上分配对象

时间:2012-09-14 11:29:10

标签: objective-c object stack

我是Objective C的新手并且使用对象进行一些练习。虽然Fraction* f = [[Fraction alloc] init ];之类的东西有效,但每当我尝试Fraction c;时,我得到Interface type cannot be statically allocated无论如何都要在堆栈上分配对象(比如在c ++中)?还是我在做错事?

6 个答案:

答案 0 :(得分:4)

您无法在Objective C中静态分配对象。这有很多原因。包括应该初始化对象但允许初始化方法更改对象地址的事实。

在C ++中,构造函数必须初始化它所调用的对象,并且不能以任何方式更改对象地址。在Objective C中不是这样。构造函数(alloc + init *序列或类级方法)的等价物被允许决定它们将改变它们被调用的对象的地址(它们将照顾当然,释放原始对象。

当然,他们无法释放静态分配的内存,也无法更改堆栈的地址。

答案 1 :(得分:2)

从技术上讲,你可以(见下面的代码),但你不应该这样做。此外,无论是在堆栈还是堆中,您只有指向对象的指针,而不是对象本身。也就是说,您应该写Fraction *c,而不是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()是非标准的,不安全的,不可移植的,并且容易出现堆栈溢出。

答案 2 :(得分:1)

不,所有对象都在Obj-C中的堆上分配。

答案 3 :(得分:1)

不,您不能将堆栈用于Objective-C对象的内存,它必须是堆(通过allocinit)。

然而,正如@ wattson12所指出的,你可以显然将对象引用(指针)存储在堆栈上,这仍然没有使用堆栈作为对象的内存。

答案 4 :(得分:0)

您遇到的错误是由于语法错误,您需要执行以下操作:

Fraction *c; 

注意缺少的*表示这是一个指向对象的指针(你没有将这个对象存储在堆栈中,你只是创建一个对(潜在)对象的引用)

答案 5 :(得分:0)

除了块对象外,所有objective-c对象都在中分配。主要原因是:

    在目标C中没有跟踪
  1. 指向对象的指针(而是Objective-C使用引用计数系统进行内存管理);如果你移动物体,它们就无法更新。
  2. 堆栈对象将在创建它们的函数返回时被销毁。
  3. 来自Mike Ash的post有助于理解这一点。