2013-12-24 28 views
0

我正在編寫一個應用程序,用戶應該能夠點擊按鈕並切換視圖。我創建了IBActions,在所需的視圖中加載了我的方法switchSubView,但這樣做一直存在一些問題。我目前已經編寫了方法來動畫化通過Interface Builder作爲IBOutlets連接的兩個NSViews之間的轉換。我可以使用這些方法在兩個視圖之間切換,但是當我嘗試從初始視圖切換到另一個視圖時,切換到另一個視圖,然後切換回來,我得到了EXC_BAD_ACCESS。我似乎無法調試該問題。調試器顯示兩個NSView對象指向不同的內存位置。爲了澄清,我希望在整個應用程序執行期間重用這些視圖。我不希望任何意見被釋放。這個NSView在哪裏被解除分配導致訪問錯誤?

下面是代碼:

- (void)switchSubViews:(NSView *)firstView withView:(NSView *)secondView { 
    [firstView setSubviews:[NSArray array]]; 
    [self prepareViews:firstView]; 
    [[firstView animator] addSubview:secondView]; 
} 

/* Make a "move" animation effect. */ 
- (void)prepareViews:(NSView *)prepareView { 
    CATransition * transition = [CATransition animation]; 
    [transition setType:kCATransitionPush]; 
    [transition setSubtype:kCATransitionFromRight]; 
    [prepareView setAnimations:[NSDictionary dictionaryWithObject:transition forKey:@"subviews"]]; 
    [prepareView setWantsLayer:YES]; 
} 

基本上,我會這樣稱呼它,因爲initialView和NewView的:

[self switchSubViews:initialView withView:newView]; 

誰能幫我調試呢?

謝謝。

更新:在註釋掉for循環和removeFromSuperview代碼來調試之後,我仍然收到錯誤的訪問錯誤。該視圖的屬性設置爲@property (nonatomic, strong),所以不應該保留視圖?如果沒有,我怎麼能明確地保留我的NSView(s)與ARC啓用?是否可以告訴ARC保留它,還是已經保留了視圖,因爲它是用@property(非原子,強)設置的?

第二次更新:我研究了一下,發現我可以通過創建一個強指針指向對象來讓ARC保留對象。我試了一下通過創建實例變量:

@interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> { 
    /* Some instance variables here... */ 
    __strong NSView * retainFirstView; 
    __strong NSView * retainSecondView; 
} 

@property (nonatomic, strong) NSView * retainFirstView; 
@property (nonatomic, strong) NSView * retainSecondView; 

然後在.m文件:

#import <Quartz/Quartz.h> /* Animation. */ 
#import "AppDelegate.h" 
/* Some other imports necessary... */ 

@implementation AppDelegate 

@synthesize retainFirstView; 
@synthesize retainSecondView; 

/* Some subview switching code... */ 
[self setRetainFirstView:firstView]; 
[self setRetainSecondView:secondView]; 

@end 

,但我仍然收到錯誤。似乎我正在交換的觀點一直被解除分配。我在這方面花了很多時間,並沒有能夠擺脫錯誤。任何幫助,將不勝感激。如果這不是保留視圖的正確方法,請告訴我。

更新3:爲了測試,我暫時禁用了ARC,並呼籲setSubviews或addSubview這樣做過:

[firstView retain]; 
[secondView retain]; 

,它仍然失敗。我很困惑,因爲我不再看到可能導致釋放的原因。

更新4:我通過在Xcode中執行產品 - >配置文件檢查殭屍和消息發送到釋放對象,令我驚訝的是,我沒有收到任何通知。我很困惑這是爲什麼發生。

回答

3

你得到EXC_BAD_ACCESS,因爲如果沒有其他人保留它,調用-removeFromSuperview將取消分配該視圖。很可能正在釋放的視圖(因此有一個指向垃圾的對象指針)稍後傳遞到-switchSubviews:withView,導致您的崩潰。在調用-removeFromSuperview以確保它們未被釋放之前,您應始終保留稍後將要使用的視圖。

作爲旁註,-switchSubviews:withView:的代碼是不必要的複雜。它可以歸結爲:

- (void)switchSubViews:(NSView *)firstView withView:(NSView *)secondView { 
    firstView.subviews = [NSArray array]; 
    [self prepareViews:firstView]; 
    [[firstView animator] addSubview:secondView]; 
} 
+0

謝謝你,我可能永遠都不會想出我自己。但我仍然有一個小問題。如果我的項目使用ARC,如何保留視圖?我不允許顯式調用保留消息。 – ra1nmaster

+0

看來,即使在註釋掉removeFromSuperview代碼以進行調試之後,該錯誤依然存在。這意味着視圖正在被釋放,但我無法從哪裏找到。我使用屬性設置視圖屬性(非原子,強大),所以這不意味着視圖應該由ARC保留? – ra1nmaster

+0

所以我應該保留firstView的每個子視圖?如果是這樣,我該怎麼做? – ra1nmaster