gpt4 book ai didi

iphone - 消息发送到应该存在的对象上的已释放实例

转载 作者:行者123 更新时间:2023-12-03 21:19:16 25 4
gpt4 key购买 nike

[CFString isEqualToString:]:发送到已释放实例的消息

这是我收到的错误。我有一个 View Controller ,其属性是 NSMutableArray,它包含一些 Player 对象。

然后我有一个切换到另一个 View 的方法,我可以在其中添加和删除玩家。当我加载下一个 View 时,我将指针传递给第一个 View 和第二个 View 。然后,我使用 [previousView.playerList addObject:p]; 更新了数组,其中 p 是新创建的玩家对象。

但是,当我尝试在第二个 View 的 TableView 中显示玩家列表时,出现错误。当我尝试访问 [previousView.playerlist objectAtIndex:[indexPath row]]; 时,出现上述错误。

代码如下:

这是在第一个 View 中,它加载第二个 View 并将其自身传递给第二个 View 的属性。

- (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 玩家名称]];

有人知道我哪里搞砸了吗?如果需要,我会发布更多代码。

我将 Player.m 修剪为仅包含综合和初始化,因为其余的代码很多,这与此错误无关,因为它没有被调用。

玩家.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

玩家.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, keep) NSMutableArray *playerList;

最佳答案

在:

- (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),但您并未使用属性 setter 在-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 保留]的目的是什么,是否有平衡释放?

另一个例子:在:

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

您从 +alloc 获得 +1 所有权,从 -retain 获得另一个 +1,并且该数组还拥有 p,因此另一个+1。您应该将 -retain 替换为 -autorelease 以平衡您获得该对象所有权的次数。

关于iphone - 消息发送到应该存在的对象上的已释放实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6492508/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com