塊存儲管理的一個邊緣殼體下面的代碼會崩潰,因爲EXC_BAD_ACCESS
理解objc
typedef void(^myBlock)(void);
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *tmp = [self getBlockArray];
myBlock block = tmp[0];
block();
}
- (id)getBlockArray {
int val = 10;
//crash version
return [[NSArray alloc] initWithObjects:
^{NSLog(@"blk0:%d", val);},
^{NSLog(@"blk1:%d", val);}, nil];
//won't crash version
// return @[^{NSLog(@"block0: %d", val);}, ^{NSLog(@"block1: %d", val);}];
}
代碼在IOS 9 ARC運行啓用。我試圖找出導致崩潰的原因。
通過po tmp
在LLDB我發現
(lldb) po tmp
<__NSArrayI 0x7fa0f1546330>(
<__NSMallocBlock__: 0x7fa0f15a0fd0>,
<__NSStackBlock__: 0x7fff524e2b60>
)
而在不會崩潰版本
(lldb) po tmp
<__NSArrayI 0x7f9db481e6a0>(
<__NSMallocBlock__: 0x7f9db27e09a0>,
<__NSMallocBlock__: 0x7f9db2718f50>
)
所以最可能的原因,我能想出是當ARC釋放NSStackBlock崩潰發生。但爲什麼會這樣呢?
感謝您的詳細解答。我相信C可變參數不是類型安全的,這是對這種情況更準確的解釋。 – dopcn
@dopcn - newacct我傾向於不同意規範在塊和ARC方面的狀態。不幸的是,蘋果的文檔並不總是那麼清晰和全面,並且不僅僅是公平的,而且涉及到一定程度的解釋。請將您的案例作爲一個錯誤提交給Apple;他們可以修復它,說它按預期工作,或者什麼都不說;但你會提醒他們。如果他們確實回覆了有用的回覆,可以將其添加到上面的問題中作爲幫助其他人的附錄。 – CRD