2013-12-18 14 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

相關問題