Objective-C中的对象是否曾在堆栈中创建?

时间:2013-12-18 16:29:23

标签: objective-c memory-management heap alloc

据我所知,在C ++中你可以在堆栈上创建对象:

SomeClass object = SomeClass();

或在堆上:

SomeClass *object = new SomeClass();

在Objective-C中,您似乎始终在堆上创建对象,因为[SomeClass alloc]返回指向新实例的指针。这是对的吗?

是否在堆栈上分配了对象?如果是这样,那将是一个很好的例子?否则,为什么不呢?

2 个答案:

答案 0 :(得分:4)

简短的回答是,对象总是在堆上分配,而不是在堆栈上。

但这并非完整的故事。在Objective-C中,块也是完整的Objective-C对象。它们的特殊之处在于它们有时会在堆栈中 。特别是,使用块文字语法创建的块以及引用周围范围的块都在堆栈中。如果你检查他们的班级,你甚至可以看到这个(私人)NSStackBlock。如果使用Block_copy()-copy复制它们,则生成的副本将位于堆上(NSMallocBlock)。

这意味着堆栈分配的块仅在创建它们的范围结束之前有效。在ARC之前(以及早期版本的ARC中的IIRC),这意味着您必须复制您希望在其创建范围之外生存的块,以便它们在堆上。 ARC现在在大多数情况下为您处理这个问题,也意味着块是在堆栈上还是在堆上更难预测。

这个小测试程序显示了这一点(使用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]));
    }
}

输出:

stackBlock class: __NSStackBlock__
heapBlock class: __NSMallocBlock__

(为了清楚起见,您当然不应该在实际代码中使用NSStackBlock / NSMallocBlock检查。它们是私有实现详细信息类。此代码仅用于演示。)< / p>

答案 1 :(得分:3)

将在堆栈上创建基本原语类型(intfloatdouble)。

实际的指针(即object中的SomeClass* object)是在堆栈上创建的,即使它指向堆上的对象

你说在堆上创建了new创建的任何内容都是正确的。