據我瞭解,在C++中,你可以在棧上創建對象:Objective-C中的對象是否曾經在堆棧上創建過?
SomeClass object = SomeClass();
或堆上:
SomeClass *object = new SomeClass();
在Objective-C,你似乎總是在堆上創建對象,因爲[SomeClass alloc]
返回一個指向新實例的指針。它是否正確?
對象是否曾被分配到堆棧上?如果是這樣,那麼這將是一個很好的例子?否則,爲什麼不呢?
據我瞭解,在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) –