2011-06-27 33 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

相关问题