2011-06-03 138 views
2

我在我的類(除了原始視圖)在界面生成器中進行UIView。切換視圖EXC_BAD_ACCESS

@interface TimeLineGrid : UIViewController { 

UIView *toggleView; 

} 

@property (nonatomic, retain) IBOutlet UIView *toggleView; 

我也綜合了它。我已經實施了一個滑動手勢,以便在刷新之後添加切換視圖,並在切換時切換視圖被刪除。

-(void)swipedUp { 

    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:2.0f]; 

    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:NO]; 

    [self.view addSubview:self.toggleView]; 

    [UIView commitAnimations]; 



} 

-(void)swipedDown { 

    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:2.0f]; 

    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO]; 

    [self.toggleView removeFromSuperview]; 

    [UIView commitAnimations]; 

} 

當我向上滑動一次,然後向下滑動時,它正常工作。但是當我再次向上滑動時,它會因EXC_BAD_ACCESS錯誤而崩潰。我知道這與保留計數增加時添加子視圖和減少當我刪除子視圖。有人可以更多地瞭解這一點嗎?我如何實現此切換?

編輯: 我的觀點的層次結構如下:

->UIView (toggleView) 
->UIView (mainView to which toggleView is being added) 
-->UIToolBar 
+5

你似乎在添加和刪除視圖。你在哪裏創建並將視圖分配給toggleView? – Dancreek 2011-06-03 14:05:25

+1

在目標的構建設置中啓用「運行靜態分析器」,以查看以何種方式進行內存管理的位置。 – 2011-06-03 14:06:23

+0

@Dancreek:它是在界面製作器中製作的。我只是將視圖連接到了toggleView插座。 – 2011-06-03 14:06:56

回答

3

最有可能的是,當您撥打[self.toggleView removeFromSuperview];時,視圖正在釋放。我建議你稍微調整你的代碼。

因爲要創建在IB的觀點,在頭文件中聲明爲

IBOutlet UIView *toggleView; 

包括屬性調用或合成。由於您沒有設置或獲取toggleView,只需通過指針引用即可。

在實現中,在viewDidUnload中將指針設置爲nil並將其釋放到dealloc中。然後,調整切換方法如下:

-(void)swipedUp { 
    if (![toggleView superview]) { 

     [UIView beginAnimations:nil context:nil]; 
     [UIView setAnimationDuration:2.0f]; 

     [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:NO]; 

     [self.view addSubview:toggleView]; 

     [UIView commitAnimations]; 
    } 
} 

-(void)swipedDown { 

    if ([toggleView superview]) { 

     [UIView beginAnimations:nil context:nil]; 
     [UIView setAnimationDuration:2.0f]; 

     [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO]; 

     [toggleView removeFromSuperview]; 

     [UIView commitAnimations]; 
    } 
} 

在此,用戶連續兩次猛擊了if子句將捕獲的事件,而不是第二個刷卡響應。還請注意,這使用toggleView代替self.toggleView

這應該可以解決問題。

+0

非常感謝! – 2011-06-12 06:39:52

+0

@ HG的你是最受歡迎的。很高興它的工作。不要忘記獎勵到期前的獎勵:-) – PengOne 2011-06-12 06:41:30

+0

哦,對不起忘了那麼回合。現在做了。再次感謝 – 2011-06-12 06:43:19

3

可否請你運用這些變化,並告訴該UIView的是完全有proble。

  1. 開放的XCode /產品/編輯計劃...
  2. 移動到環境變量,然後點擊加號添加變量
  3. 添加變量NSZombieEnables - 值:是
  4. 添加變量MallocStackLoggingNoCompact - 值: 1

啓動應用程序後,您會看到,在調用它時,確切地說明了哪個對象。

+0

真正有用的信息!謝謝。 – windson 2011-09-22 23:19:57

1

我建議您製作您想要顯示/隱藏的視圖,均爲子視圖的容器視圖。然後,在動畫塊中,首先刪除消失的視圖並添加要顯示的視圖。例如:

@interface TimeLineGrid : UIViewController { 
    // declare the views you want to flip between 
    UIView *mainView; 
    UIView *toggleView; 
} 

@property (nonatomic, retain) IBOutlet UIView *mainView; 
@property (nonatomic, retain) IBOutlet UIView *toggleView; 

在您的實現:

// self.view is the container view (an instance of UIView). 
// Initially, self.mainView is a subview of self.view 

-(void)transitionFromView:(UIView *)fromView toView:(UIView *)toView withAnimation:(UIViewAnimationTransition)animation { 

    if ([toView superview]) { 
     // toView already shown 
     return; 
    } 

    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:2.0f]; 

    [UIView setAnimationTransition:animation forView:self.view cache:NO]; 

    [self.view removeFromSuperview:fromView]; 
    [self.view addSubview:toView]; 

    [UIView commitAnimations]; 

} 

-(void)swipedUp { 
    [self transitionFromView:self.mainView 
         toView:self.toggleView 
       withAnimation:UIViewAnimationTransitionFlipFromLeft]; 
} 

-(void)swipedDown { 
    [self transitionFromView:self.toggleView 
         toView:self.mainView 
       withAnimation:UIViewAnimationTransitionFlipFromRight]; 
} 

不過請注意,使用該方法setAnimationTransition:forView:cache:現在氣餒。 Apple建議使用UIView transitionWithView:duration:options:animations:completion:方法(請參閱UIView reference)。

我希望這有助於!

1

我做了一個包含UITabbar的應用程序,並得到了與UIButton相同的行爲。

發生這種情況時,您不會釋放您呼叫的對象removeFromSuperview,我從我的viewControllers視圖中刪除UIButton時,具有相同的效果。

在我的情況下,我仍然可以看到按鈕,如果我點擊它,我會得到一個異常,如無法識別的選擇器發送到NSCFString類型的對象。

但是,如果我改變選項卡,然後返回到我的視圖控制器,其中按鈕之前顯示從我的視圖中刪除它後,它已經消失。

所以我的結論是,如果你不鬆開,你的呼籲removeFromSuperview的對象,然後應用程序會表現出一些意外的行爲,如果你有對象的類的實例變量,並通過addSubView它添加到視圖編程方法。

您有哪些選擇: -

  1. 你可以叫上一個UIView或它的子類的對象removeFromSuperview,並呼籲釋放它或使其爲零。

  2. 您可以使用hidden屬性隱藏或取消隱藏這些對象,而不是將它們從超級視圖中刪除。

  3. (我還沒有嘗試過精確地)你可以在你的類實現創建UIView對象,然後將其添加爲subview,然後用點操作將其分配到您的實例變量的類,然後釋放先前創建的UIView對象。

我不知道我的答案可能對你有幫助,但我認爲它很好與其他人分享你的經驗。