最近我瞭解到如果我需要保留一個塊對象,我應該複製該塊,因爲它是在堆棧上創建的。iOS塊對象沒有複製?
然後我回顧一下我的代碼。我發現我做的是這樣的:
@implementation MyView
...
-(void) addButton:(NSString *)title clickAction:(void ^(void)) action {
[self.buttons addObject:@[ title, action ] ];
}
-(void) createButtons { ... }
...
@end
...
// Somewhere in my project:
-(void) init {
MyView *view = [MyView new];
[view addButton:@"OK" clickAction:^{ NSLog(@"OK"); }];
[view addButton:@"Cancel" clickAction:^{ NSLog(@"Cancel"); }];
}
基本上,我添加一些按鈕的信息給MyView。在某個時候,MyView會創建按鈕。當按鈕被點擊時,MyView會找出相應的clickAction,並調用它。
奇怪的是,這個程序工作正常,沒有例外,沒有錯誤。
那麼,爲什麼程序運行時沒有複製塊對象呢?
其他信息: * iPhone應用程序(4.3 - 6.0) *非ARC *的XCode 4.5
我敢肯定,無論塊有多複雜,代碼仍然可以工作,因爲'action'被放置在'NSArray'中,這會導致它被集合保留... –
@JodyHagins Retaining不是問題在於,堆棧上分配的主體超出了範圍,會導致問題。當該方法存在時,其內部創建的塊將最終存儲在內存的無效區域中。這就是爲什麼你需要將它複製到堆上。 – dasblinkenlight
正確 - 但當NSArray保留它時,它會被複制到堆中。從此,NSArray中的對象將成爲堆版本,而不是原始堆棧塊。如果您在基於堆棧的塊上調用retain,它會將其複製到堆中,然後保留它。 –