Objective-C中的对象是否曾经在堆栈上创建过?
问题描述:
据我了解,在C++中,你可以在栈上创建对象:Objective-C中的对象是否曾经在堆栈上创建过?
SomeClass object = SomeClass();
或堆上:
SomeClass *object = new SomeClass();
在Objective-C,你似乎总是在堆上创建对象,因为[SomeClass alloc]
返回一个指向新实例的指针。它是否正确?
对象是否曾被分配到堆栈上?如果是这样,那么这将是一个很好的例子?否则,为什么不呢?
答
简短的回答是对象总是分配在堆上,而不是在堆栈上。
虽然这不是全部。在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
在实际代码中,它们是私有实现细节类,这段代码仅供演示使用)
答
what abou t int x = 0; ?(目标C) –