据我所知,在C ++中你可以在堆栈上创建对象:
SomeClass object = SomeClass();
或在堆上:
SomeClass *object = new SomeClass();
在Objective-C中,您似乎始终在堆上创建对象,因为[SomeClass alloc]
返回指向新实例的指针。这是对的吗?
是否在堆栈上分配了对象?如果是这样,那将是一个很好的例子?否则,为什么不呢?
答案 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)
将在堆栈上创建基本原语类型(int
,float
和double
)。
实际的指针(即object
中的SomeClass* object
)是在堆栈上创建的,即使它指向堆上的对象
你说在堆上创建了new
创建的任何内容都是正确的。