2010-06-23 88 views
3

我有一個情況我偶爾方法-tableView: numberOfRowsInSection:請求解除分配的NSArray的計數。我希望能夠測試這個數組是否以安全的方式釋放,並且不會打電話給殭屍。測試對象是否已釋放

我的代碼目前是這樣的:通過這個

-(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section 
{ 
    if (! self.offers){ 
     return 0; 
    } 
    return [self.offers count]; 
} 

我剛剛調試階梯並觀察它傳遞! self.offers測試,然後在[self.offers count]慘遭崩潰。我已經NSZombies打開,並且在該行我得到的NSLog消息:

-[__NSArrayM count]: message sent to deallocated instance 0x283dc0 

所以,無論是self.offers,在這一點上,是不是零,但也沒有任何在有效指出。我該如何測試?

編輯:感謝艱難的愛情,朋友。我想出了爲什麼我一直在處理內存管理問題 - 實際上這是一個代表關係的問題,它們拖延的時間比它們有用的時間要長。看到這裏的完整回答我的問題: Managing calls to objects that get deallocated when the view is backed out of

+0

可能重複[如何確定如果我有一個指針釋放的對象?](http://stackoverflow.com/questions/12280799/how-to-determine- if-i-have-a-pointer-to-released-object) – OrangeDog 2014-01-17 12:34:55

回答

15

這是不可能的「測試」 this--一旦對象被釋放,它不見了,指針它實際上是垃圾。用它做任何事情都容易崩潰。

對不起,壞消息的傳播者,但讓這個工作正確的唯一方法是確保內存管理(在這種情況下)offers在所有用途上都是正確的 - 保留並正確釋放該實例變量被操縱的點,它永遠不會是非零垃圾。

你應該嘗試運行靜態分析(建設 - >建立與分析)開始with--這個工具可以幫助標記存儲管理模式問題,而你的一部分很多額外的挖掘。

+2

+1,一旦你放棄了它的所有權,將'offers'設置爲'nil'。這樣,您可以將代碼更改爲'return [self.offers count];',因爲'[nil count]'返回0. :) – 2010-06-23 14:25:12

1

你應該通過固定的代碼,以便它不釋放數組的時候,你顯然還需要避免的問題。

0

這可能不是有關您的問題(測試如果它被釋放) - 但似乎你提供陣列具有相同或更長的壽命比你UITableViewController,是您確定您保留這個數組,或者你不會意外地將它釋放到別處。

0

我同意quixoto上面所說的。

你要問自己的另一件事是,我的應用程序設計正確? tableview依賴於一個數據源來填充它(在你的情況下,它是offers數組),所以如果你在代碼中的某個地方釋放它,那麼你需要退後一步並重新考慮你的設計。

如果您正在測試無論是釋放,因爲你是從以前的問題,試圖「修復」它,那麼它可能是值得尋找到你的代碼,看到它被保留/釋放。

0

是,一旦一個對象被釋放,它不見了,指針它實際上是垃圾。用它做任何事情都容易崩潰。

但是它是可以測試的。有一個解決方法。 (雖然解決方法不能取代良好的設計實踐!): 您有一個全局BOOL變量,您可以在alloc上設置該變量。以下是用於檢查AVAudioPlayer是否正在播放的示例。如果它正在播放,並且視圖已關閉,則應用程序會崩潰。由於後臺線程等原因,簡單地停止音樂不是一種選擇。但是,當newPlayer已經發布時調用[newPlayer isPlaying]會崩潰!所以BOOL標誌解決方法使其工作。 (這個有什麼好的設計實踐的意見將是有價值的。)

// In implementation 
static AVAudioPlayer *newPlayer; 
static BOOL hasMusicFinishedPlaying; 

// When Playing the music, set flag 
    newPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: soundPath] error:nil];  
    hasMusicFinishedPlaying = NO; 

// Callback method to release new player in playKeySound 
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)newPlayer successfully:(BOOL)flag { 

    [newPlayer release]; 
    hasMusicFinishedPlaying = YES; 
} 

// On going back to another page. We don't want to keep ViewController in stack. 

    if (!hasMusicFinishedPlaying){ 
     return; 
    } 

    [self.navigationController popViewControllerAnimated:YES]; 
1

您可以添加

-(void)dealloc { ... } 

,讓它空,如果是做正確的,並在其中添加斷點。

這個答案正確ARCNON-ARC

+1

'dealloc'在非弧中不能爲空。您必須*擁有'[super dealloc]'作爲此方法的最後一行。 – 2015-09-14 17:19:09