2013-12-18 62 views
2

据我了解,在C++中,你可以在栈上创建对象:Objective-C中的对象是否曾经在堆栈上创建过?

SomeClass object = SomeClass(); 

或堆上:

SomeClass *object = new SomeClass(); 

在Objective-C,你似乎总是在堆上创建对象,因为[SomeClass alloc]返回一个指向新实例的指针。它是否正确?

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

+0

what abou t int x = 0; ?(目标C) –

回答

4

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

虽然这不是全部。在Objective-C中,块也是完整的Objective-C对象。他们很特殊,因为他们有时在堆叠上有。特别是,使用块文字语法创建的块以及引用周围范围的块位于堆栈上。你可以看到这个,如果你检查他们的班级,这将是(私人)NSStackBlock。如果使用Block_copy()-copy复制它们,结果副本将位于堆上(NSMallocBlock)。

其中一个含义是堆栈分配的块只在其创建范围的末尾有效。在ARC之前(以及在ARC的早期版本中IIRC),这意味着你必须复制你想要超越其创建范围的块,以便它们在堆上。 ARC现在在大多数情况下都会为你处理这个问题,也意味着一个块是否在堆栈中或堆很难预测。

这个小测试程序显示了这一点(与ARC 编译关闭):

#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在实际代码中,它们是私有实现细节类,这段代码仅供演示使用)

3

基本原始类型(int,floatdouble)将在堆栈上创建。

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

你说的任何东西都是用堆创建的new

+0

我知道原语和指针。但是实际的对象从来不会放在堆栈上,即使你想要,你也不能做到这一点? – Jawap

+0

不,他们不是所有的对象都是用'new'创建的。 – Bathsheba

+1

你的意思是“所有对象都是用'new'创建的”?在Objective-C中?你不是指'alloc'吗?据了解,Objective-C中的'new'只是alloc/init的一个快捷方式。 – Jawap

相关问题