1

我對塊和ARC的理解存在差距,我希望得到一些幫助。我收到了一個源自動畫完成塊的測試器的崩潰報告。碰撞如下:在ARC下的塊中聲明的對象的生命週期是多少?

異常類型:EXC_BAD_ACCESS(SIGSEGV)

異常代碼:KERN_INVALID_ADDRESS在0xf0000010

這是以下的動畫完成塊內發生(使用animateWithDuration:animations:completion:)。我使用的臨時變量交換兩個視圖控制器:

{ 
    [current wasMovedOffScreen]; 
    PlayerViewController *temp = current; 
    current = next; 
    next = temp; 
} 

next = temp;是其上發生崩潰的行。動畫的持續時間是0.3秒。

此代碼在視圖控制器內部執行,該視圖控制器充當兩個其他視圖控制器的容器,用於模擬用戶通過列表中的對象,如導航控制器,但具有一些定製控制器不適合我。

這兩個子視圖控制器被稱爲「當前」和「下一個」 - 您可以猜到當前控制器顯示當前內容,並且當用戶在列表中移動時,下一個用於在新項目中設置動畫。

如果我更改塊以便在執行中聲明temp(與currentnext一起),崩潰停止。然而,我不需要爲一個本地和臨時定義的東西舉辦一個階級ivar。

所以,

  • 爲什麼temp顯然是由ARC在此過程中釋放?
  • 執行此操作的正確方法是什麼?是否有一些生命週期限定符應添加到塊實施中?
  • 爲什麼我不能在自己的設備或模擬器上重現崩潰?這兩款設備都是iPhone 4運行相同版本的iOS(5.0.1)。

回答

0

如果它確實讓你起牀,因爲你只是在兩個視圖之間交替,你實際上並不需要所有這些當前/下一個業務。那麼,如果你願意的話,你可以跟蹤當前的情況......但這是主意。

如果您有屬性:

@property (nonatomic, strong) UIViewController *controller1; 
@property (nonatomic, strong) UIViewController *controller2; 
@property (nonatomic, weak) UIViewController *currentController; 

然後你就可以有一個方法:

- (id)swapControllers { 
    // use the current controller to figure out what the next controller is, so 
    // you don't have to do the two way swap. do in the completion, if you like.  
    UIViewController *nextController = ([self.currentController isEqual:self.controller1]) ? self.controller1 : self.controller2; 
    [UIView animateWithDuration:.25 
        animations:^{ 
         // TODO: some animations on currentController and nextController 
        } completion:^(BOOL finished) { 
         [self.currentController wasMovedOffScreen]; 
         self.currentController = nextController; 
        }]; 
} 

至於你原來的問題,ARC知道如何處理塊相當不錯 - 如果你沒有使用它,我可能會問你是否忘記複製其他地方聲明的塊,然後存儲,然後作爲完成處理程序傳入。由於情況並非如此,並且由於您無法獲得repro ...我猜測您可能正在運行beta sdk--最近的beta版本中存在一些ARC漏洞。如果是這樣,你可以嘗試用最後一個穩定版本來構建,看看你是否能獲得更好的結果。

+0

沒有貝塔斯參與,缺乏repro真的很煩我! – jrturton 2012-01-15 15:15:44

1

我不認爲這個問題實際上是ARC。變量(包括局部變量)默認爲__strong,所以current應保留在第一個賦值中。

http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html - 見「可變量詞

如果你有無法重現自己崩潰,它總是會很難修復。你有沒有嘗試在調試器之外運行應用程序?加載調試器有時可以改變行爲。另外,嘗試使用NSZombieEnabled或Instruments.app的殭屍工具進行調試。

相關問題