gpt4 book ai didi

objective-c - 升级到适用于 iOS 的 SDK 5 后从 NSMutableArray 中删除对象会导致我的应用程序崩溃

转载 作者:行者123 更新时间:2023-11-28 23:10:55 27 4
gpt4 key购买 nike

[编辑] 我重新安排了从列表中删除 obj 的方式。这就是它最初仍然导致相同错误的原因。

这是有问题的代码。我相信我已将错误缩小到从 _blocks NSMutableArray 中删除对象的那一行。我在代码的其他部分有完全相同的代码,从同一个数组中删除了类似的对象。出于某种原因,调用此函数会导致游戏崩溃。在我升级到最新的支持iOS SDK 5和armv7的XCode之前没有这个问题。在我升级 XCode 之前,它运行良好。我会走进一个项目,然后这个项目就会从屏幕上消失。现在它只是在我得到一个项目时崩溃。任何帮助将不胜感激。

-(void)itemCollision:(Collidable *)obj :(int)itemID :(int)objID: (bool)withPlayer{
[background removeChild:[obj getSprite] cleanup:YES];
[background removeChild:[obj getArrow] cleanup:YES];
[_blocks removeObject:obj];
//[obj release];
if(withPlayer){
if(itemID == 1){
[[SimpleAudioEngine sharedEngine] playEffect:@"Item2.mp3" pitch:1.0f pan:0.0f gain:0.3f];
points += (10 + level * 22);
}
}

#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
[pool release];
return retVal;

当应用程序崩溃时,它会突出显示这一行:

int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");

错误消息是:“线程 1:程序接收到信号:“SIGARBRT”。

这是我调用 itemCollision 的代码:

-(bool) isCollision {
CCSprite *playerSprite = mob;//[mob getSprite];

CGRect playerRect = CGRectMake(playerSprite.position.x - (playerSprite.contentSize.width/2),
playerSprite.position.y - (playerSprite.contentSize.height/2),
playerSprite.contentSize.width,
playerSprite.contentSize.height);

//Player Collision

BOOL collision = FALSE;

for (Block *block in _blocks) {
CCSprite *blockSprite = [block getSprite];
CGRect blockRect = CGRectMake(blockSprite.position.x - (blockSprite.contentSize.width/2),
blockSprite.position.y - (blockSprite.contentSize.height/2),
blockSprite.contentSize.width,
blockSprite.contentSize.height + 1 + [mob getSpeed]);
if (CGRectIntersectsRect(blockRect, playerRect)) {
if ([block getItemID] != 0) {
[self itemCollision:block :[block getItemID] :[block getID] :TRUE];
continue;
}
if(playerSprite.position.y > blockSprite.position.y){
collision = TRUE;
}
if(collision) {
[[SimpleAudioEngine sharedEngine] playEffect:@"squish.caf"];
[self die];
return TRUE;
}
}
}
return FALSE;

以下是我如何从代码其他地方的 _blocks 中删除对象。这是在重力定时器函数中:

NSMutableArray *blocksToDelete = [[NSMutableArray alloc] init];

for (Block *block in _blocks) {
CCSprite *blockSprite = [block getSprite];
//[block addSpeed:gravity];
[block setPreX:blockSprite.position.x];
[block setPreY:blockSprite.position.y];
blockSprite.position = ccp(blockSprite.position.x, blockSprite.position.y - [block getSpeed]);
if (blockSprite.position.y < -30 + blockSprite.contentSize.height / 2) {
[blocksToDelete addObject:block];
}
if(blockSprite.position.y - blockSprite.contentSize.height < [block getArrow].position.y){
[block getArrow].visible = FALSE;
}
}

for (Block *b in blocksToDelete) {
[_blocks removeObject:b];
[background removeChild:[b getSprite] cleanup:YES];
[background removeChild:[b getArrow] cleanup:YES];
[b release];
}

我在项目到达被此功能删除的地步之前到达项目。同样,这段代码已经工作了几个月,直到我升级了我的 XCode。

最佳答案

如果数组在对象上有最后一个保留,当你删除它时它会被释放。您继续在方法的其余部分使用该对象,因此它需要保持事件状态。当然检查obj的retainCount看NSMutableArray有没有最后的retain是最先开始的。

如果我们暂时假设是这种情况,那么试试这个替代方法:

-(void)itemCollision:(Collidable *)obj :(int)itemID :(int)objID: (bool)withPlayer
{
[[obj retain] autorelease];
[_blocks removeObject:obj];
[background removeChild:[obj getSprite] cleanup:YES];
[background removeChild:[obj getArrow] cleanup:YES];
if(withPlayer){
if(itemID == 1){
[[SimpleAudioEngine sharedEngine] playEffect:@"Item2.mp3" pitch:1.0f pan:0.0f gain:0.3f];
points += (10 + level * 22);
}
}
}

当调试器转到 main.m 时,通常是因为它在弹出自动释放池时快要死了——这是一个您没有调试符号的任务,所以它会转到它有源代码显示的最深堆栈帧你,在主线程上的自动释放池的情况下,将是你的 main() 函数。

您还应该尝试使用 Instruments 中的 Zombies 工具运行此案例。这对于跟踪这些东西非常有帮助。

关于objective-c - 升级到适用于 iOS 的 SDK 5 后从 NSMutableArray 中删除对象会导致我的应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8298282/

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