2011-06-27 62 views
2

[CFString isEqualToString:]: message sent to deallocated instance消息應該存在

這是我得到的錯誤。我有一個視圖控制器的屬性是一個NSMutableArray,它包含一些Player對象。

然後我有一個方法切換到另一個視圖,我可以添加和刪除播放器。當我加載下一個視圖時,我將一個指向第一個視圖的指針傳遞給第二個視圖。然後我使用[previousView.playerList addObject:p];更新了陣列,其中p是新創建的播放器對象。

但是當我嘗試在第二個視圖的表格視圖中顯示玩家列表時出現錯誤。當我嘗試訪問[previousView.playerlist objectAtIndex:[indexPath row]];時,出現上述錯誤。

下面的代碼:

這是第一個視圖,它加載第二個並將自己第二的財產。

- (IBAction) addPlayerButton:(id)sender { 
    [self retain]; 
    PlayerListViewController *playerListViewController = [[PlayerListViewController alloc] init]; 
    playerListViewController.previousView = self; 
    [UIView transitionFromView:self.view toView:playerListViewController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil]; 
} 

這是我初始化播放器並將其添加到數組的地方。

- (IBAction)addPlayer:(id)sender { 
    Player *p = [[[Player alloc] initWithPlayerName:playerNameField.text withOrder:[previousView.playerList count] withDelegate:previousView] retain]; 
    [previousView.playerList addObject:p]; 
    [playerNameField resignFirstResponder]; 
    [playerTableView reloadData]; 
} 

這裏是從哪裏獲得我的錯誤

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *cellIdentifier = @"MyCell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; 
    } 
    Player* p = [previousView.playerList objectAtIndex:[indexPath row]]; 
    [cell.textLabel setText:[p playerName]]; 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 

    return cell; 
} 

我得到的,我設置單元格文本行的錯誤。 [cell.textLabel setText:[p playerName]];

有沒有人知道我在哪裏搞砸了?如果需要,我會發布更多的代碼。

我修剪Player.m只包括綜合和初始化,因爲其餘的是很多代碼,這並不是真的與這個錯誤,因爲它不被稱爲。

Player.h

@protocol playerProtocol <NSObject> 

@optional 
- (void) playerDied:(id)playerObject; 
- (void) playerWasAdded:(id)playerObject; 
- (void) playerLifeDidChange:(id)playerObject; 
@end 

@interface Player : NSObject { 
    id <playerProtocol> delegate; 
} 
@property (nonatomic,retain) NSString *playerName; 
@property (nonatomic, readwrite) int playerLife; 
@property (nonatomic, readwrite) int playerPoison; 
@property (nonatomic, readwrite) int order; 
@property (nonatomic, readwrite) Boolean invincible; 
@property (nonatomic, assign) id <playerProtocol>delegate; 
@property (nonatomic, retain) UIView *viewPane; 
@property (nonatomic) Boolean shown; 
@property (nonatomic, readwrite) int minusButton; 
@property (nonatomic, readwrite) int plusButton; 
@property (nonatomic, retain) UIImageView *readout; 
@property (nonatomic, retain) NSArray *playerLifeNumerals; 


- (id) initWithPlayerName:(NSString *)playersName withOrder:(int)Order withDelegate:(id)d; 
- (void) setPlayerLife:(int)pplayerLife; 
- (void) setPlayerPoison:(int)pplayerPoison; 
- (NSArray *) getLifeNumeralsFromPlayer:(Player *)playerObject; 

@end 

Player.m

@implementation Player 

@synthesize playerLife, playerName, playerPoison, order, delegate, invincible, viewPane, readout, shown, minusButton, plusButton, playerLifeNumerals; 

#pragma mark - Custom Initalizer 

- (id) initWithPlayerName:(NSString *)playersName withOrder:(int)Order withDelegate:(id)d { 

    [super init]; 
    delegate = d; 
    playerLife = 20; 
    playerPoison = 0; 
    order = Order; 
    playerName = playersName; 
    invincible = NO; 
    [delegate playerWasAdded:self]; 
    viewPane = nil; 
    readout = nil; 
    shown = NO; 
    return self; 
} 

而且這裏的數組聲明@property (nonatomic, retain) NSMutableArray *playerList;

+0

你應該發佈'Player'的聲明和實現。 – 2011-06-27 12:06:40

回答

1

在:

- (id) initWithPlayerName:(NSString *)playersName withOrder:(int)Order withDelegate:(id)d { 

    [super init]; 
    delegate = d; 
    playerLife = 20; 
    playerPoison = 0; 
    order = Order; 
    playerName = playersName; 
    invincible = NO; 
    [delegate playerWasAdded:self]; 
    viewPane = nil; 
    readout = nil; 
    shown = NO; 
    return self; 
} 

你是不是retaini ng playerName。請注意,儘管您已將playerName屬性聲明爲retain(而應該是copy),但您並未使用-initWith…中的屬性設置器。相反,您直接訪問支持實例變量。由於您直接將playersName分配給實例變量,因此您需要手動發送它-retain(或更好的-copy)。

檢查您的其他聲明屬性是否需要該屬性。此外,您應該遵循以下成語:

self = [super init]; 
if (self) { … } 
return self; 

在您的初始器中。

編輯:由於您在多個位置泄漏,您需要仔細檢查您的代碼與內存管理實踐有關。例如,在:

- (IBAction) addPlayerButton:(id)sender { 
    [self retain]; 
    PlayerListViewController *playerListViewController = [[PlayerListViewController alloc] init]; 
    playerListViewController.previousView = self; 
    [UIView transitionFromView:self.view toView:playerListViewController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil]; 
} 

什麼的[self retain]的目的,是有一個平衡的釋放?

又如:在:

Player *p = [[[Player alloc] initWithPlayerName:playerNameField.text withOrder:[previousView.playerList count] withDelegate:previousView] retain]; 
[previousView.playerList addObject:p]; 

你從+alloc +1所有權,另一+1-retain,數組還擁有p,因此另一個+1。您應該將-retain替換爲-autorelease以平衡您獲得該對象所有權的次數。

+0

是的,我只是試圖找到這個bug之前,我保留和發佈此代碼。它通常需要我一段時間才能做到。 – Weston

+0

工作了不起,你是一個神!我希望我能給你+100。那整個週末一直在困擾着我。 – Weston

+0

關於這段代碼的另一個問題,如果你不介意,你知道一個很好的教程,解釋什麼時候應該使用複製或保留?我的iOS編程書真的只解釋了保留。 – Weston

相關問題