考慮下面的代碼塊屬性直接設置崩潰iOS版:當訪問
self.someA = [[ClassA alloc] init];
[self.someA giveBlock:^{
NSLog(@"self = %@", self);
}];
dispatch_async(dispatch_get_main_queue(), ^{
self.someA.blockCopy();
self.someA = nil;
});
如果我運行內置的O3
,啓用了ARC,在iOS上,它在objc_retain
內的self.someA.blockCopy();
調用期間崩潰。爲什麼?
現在我意識到人們可能會說我應該用self.blockCopy = inBlock
來設置它,但我確實認爲ARC應該在這裏做正確的事情。
.align 2
.code 16
.thumb_func "-[ClassA giveBlock:]"
"-[ClassA giveBlock:]":
push {r7, lr}
movw r1, :lower16:(_OBJC_IVAR_$_ClassA.blockCopy-(LPC0_0+4))
mov r7, sp
movt r1, :upper16:(_OBJC_IVAR_$_ClassA.blockCopy-(LPC0_0+4))
LPC0_0:
add r1, pc
ldr r1, [r1]
add r0, r1
mov r1, r2
blx _objc_storeStrong
pop {r7, pc}
正在調用objc_storeStrong
這又做了塊上的retain
和老塊上的release
:如果我看的組件(ARMv7的)從giveBlock:
方法,它看起來像這樣產生的。我的猜測是ARC沒有正確地注意到它是一個塊屬性,因爲我認爲它應該調用objc_retainBlock
而不是正常的objc_retain
。
或者,我只是完全錯誤,實際上ARC正在做它的文件,我剛剛讀了它的錯誤方式?
非常歡迎討論 - 我覺得這很有趣。
注意要點:
- 它不會在OS X
- 它不會崩潰建
O0
崩潰。
雖然在分配時看到「objc_storeStrong」,但我沒有能夠「做正確的事情」,我只是有點驚訝。 – mattjgalloway 2012-01-11 19:00:14
+1有趣! – Till 2012-01-11 19:02:08
根據我的理解(有一段時間),有些情況會阻止編譯器發出在所有情況下都「正常工作」的代碼。在ARC之下,沙地中的堅硬線條要求編譯器能夠準確地證明任何給定的代碼模式始終在任何地方都能正常工作。在這種情況下,它不能這樣做,因爲通過任何給定調用站點(包括'objc_storeStrong()')傳遞的僅堆棧塊參數有效。 – bbum 2012-01-11 20:56:51