[CFString isEqualToString:]: message sent to deallocated instance
这是我得到的错误。我有一个View控制器,其属性是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修剪为仅包含Synthesis和Initalization,因为其余的是很多代码,这与这个错误没有关系,因为它没有被调用。
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 :(得分: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;
}
您没有保留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]
的目的是什么,是否有平衡释放?
另一个例子:in:
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
,以平衡您获得该对象所有权的次数。