1

所以这是理解我的问题所需的背景代码。在我的视图控制器类中,我有一个方法可以创建一个名为 levelStart 的数组,然后将该数组发送到我的游戏类,该类使用该数组进行自我初始化,然后我有一组函数使用该数组“玩游戏” . 这是视图控制器代码:

    NSMutableArray* levelStart = [[NSMutableArray alloc] init];
    NSMutableArray* levelFinish = [[NSMutableArray alloc] init];
    NSString* startString = [[NSString alloc] initWithString:@"9999999999988888888998888888899888888889988888888998888888899888888889911888888991188888899999999999"];
    NSString* finishString = [[NSString alloc] initWithString:@"9999999999988888811998888881199888888889988888888998888888899888888889988888888998888888899999999999"];
    int currentsquare;
    for (int i = 0; i < 100; i++) {
        currentsquare = [startString characterAtIndex:i] - '0';
        if (currentsquare == 1) {
            NSNumber* numb1 = [[NSNumber alloc] initWithInt:1];
            [levelStart addObject:numb1];
        }
        if (currentsquare == 2) {
            NSNumber* numb2 = [[NSNumber alloc] initWithInt:2];
            [levelStart addObject:numb2];
        }
        if (currentsquare == 3) {
            NSNumber* numb3 = [[NSNumber alloc] initWithInt:3];
            [levelStart addObject:numb3];
        }
        if (currentsquare == 4) {
            NSNumber* numb4 = [[NSNumber alloc] initWithInt:4];
            [levelStart addObject:numb4];
        }
        if (currentsquare == 8) {
            NSNumber* numb8 = [[NSNumber alloc] initWithInt:8];
            [levelStart addObject:numb8];
        }
        if (currentsquare == 9) {
            NSNumber* numb9 = [[NSNumber alloc] initWithInt:9];
            [levelStart addObject:numb9];
        }
    }
    for (int i = 0; i < 100; i++) {
        currentsquare = [finishString characterAtIndex:i] - '0';
        if (currentsquare == 1) {
            NSNumber* fnumb1 = [[NSNumber alloc] initWithInt:1];
            [levelFinish addObject:fnumb1];
        }
        if (currentsquare == 2) {
            NSNumber* fnumb2 = [[NSNumber alloc] initWithInt:2];
            [levelFinish addObject:fnumb2];
        }
        if (currentsquare == 3) {
            NSNumber* fnumb3 = [[NSNumber alloc] initWithInt:3];
            [levelFinish addObject:fnumb3];
        }
        if (currentsquare == 4) {
            NSNumber* fnumb4 = [[NSNumber alloc] initWithInt:4];
            [levelFinish addObject:fnumb4];
        }
        if (currentsquare == 8) {
            NSNumber* fnumb8 = [[NSNumber alloc] initWithInt:8];
            [levelFinish addObject:fnumb8];
        }
        if (currentsquare == 9) {
            NSNumber* fnumb9 = [[NSNumber alloc] initWithInt:9];
            [levelFinish addObject:fnumb9];
        }
    }
    [startString release];
    [finishString release];
 //NOTE: I took out the intialization of control and level, both which work fine.
    myGame = [[Game alloc] initLevel:level With:levelStart AndFinish:levelFinish WithRows:10 WithColumns:10 WithControl:control];

在我的 Game 类中,这是初始化方法:

-(id)initLevel:(int)aLevel With:(NSMutableArray*)starter AndFinish:(NSMutableArray*)finisher WithRows:(int)rows WithColumns:(int)cols WithControl:(Coord)aControlSquare{
self = [super init];
if (self != nil){
    level = aLevel;
    squares = [[NSMutableArray alloc] init];
    squares = starter;
    finish = [[NSMutableArray alloc] init];
    finish = finisher;
}
return self;
}

现在它一直冻结的方法是在游戏中,由 UIgesture 识别器触发,这里是它冻结的行:

 if ([[self squareForCoord:test] intValue] == 8) {
 ...
 }

其中 squareForCord 获取测试坐标并返回该坐标处的 NSNumber。所以我确保我所有的测试都在界限内,并且它冻结的点在我的数组的范围内。我相信我正在正确初始化所有内容,但显然不是,这绝对不是发布发布的问题,所以我认为这一定是初始化问题,请帮忙。

4

2 回答 2

2

您的代码中存在一些问题,但我没有看到 EXC_BAD_ACCESS 源,但我对找到它有一些建议。

在此之前 - 以下是您可能想要修复的其他一些问题

  1. 如果你像这样初始化本地字符串

    NSString* startString = @"9999999999988888888998888888899888888889988888888998888888899888888889911888888991188888899999999999";
    

    没有必要释放它们。这使您更有可能正确执行此操作。

  2. 遍历字符时,不要硬编码长度。使用字符串的长度

    for (int i = 0; i < [startString length]; i++) {
    
  3. 你所有的 if 块都是这样的

    if (currentsquare == 1) {
        NSNumber* numb1 = [[NSNumber alloc] initWithInt:1];
        [levelStart addObject:numb1];
    }
    

    可以通过这样做来替换(但是,请先阅读#4)

    NSNumber* numb1 = [[NSNumber alloc] initWithInt:currentsquare];
    [levelStart addObject:numb1];
    

    无需检查每个可能的数字

  4. 上面的代码泄漏了,所以真的应该是这样

    NSNumber* numb1 = [NSNumber numberWithInt:currentsquare];
    [levelStart addObject:numb1];
    

    每当您分配时,您可能需要释放,除非您将该责任转交给其他人。如果您阅读addObject文档,您会看到它调用了保留,因此它不对您的发布负责。在这种情况下 numberWithInt 返回一个自动释放的对象。

  5. 这段代码

    squares = [[NSMutableArray alloc] init];
    squares = starter;
    

    立即泄漏第一个数组。您将正方形设置为一个数组对象,然后设置一个完全不同的对象。对第一个的引用丢失了。应该删除第一行(与完成类似)。

如果这是一个新项目,那么我建议您立即将其转换为 ARC。这将使处理内存更容易。

但是,如果由于某种原因你不能,请阅读我写的解释 EXC_BAD_ACCESS 的博客:

http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

简要(阅读后)这是我建议你做的

  1. 运行分析并修复它发现的每一个错误。它使用与 ARC 相同的算法,并且很可能它指出的每个错误都是一个真正的问题(它会指出上面的问题 #4 和 #5)

  2. 打开僵尸。我知道您认为您没有向已发布的对象发送消息,并且上面的代码中没有任何实例,但根据我所看到的,我认为很有可能存在。僵尸是保留计数为零的对象。当僵尸打开时,这些对象不再被释放,而是当你向它们发送消息时它们只会抱怨。

如果您在执行此操作后找不到问题,请查看博客中的其他建议。

于 2012-04-12T17:56:34.337 回答
0

First off, do you ever release levelStart and levelFinish arrays in your first class implementation? If so this is the clear issue as you are not retaining these objects after you instantiate your second class. My suggestion is to use properties to hold your arrays in the second class. Something like

 @property (nonatomic, retain)  NSMutableArray      *squares;
 @property (nonatomic, retain)  NSMutableArray      *finish;

In your declaration followed by:

@synthesize squares, finish;

In your .m file and then finally make the assignments like so in your initializer:

   self.squares = starter;
   self.finish = finisher;

Now you have a retained copy in the new class. Also I would consider using:

   myGame = [[Game alloc] initLevel:level With:[ levelStart autorelease ] AndFinish:[levelFinish autorelease] WithRows:10 WithColumns:10 WithControl:control];

for improved readability. Also, I would consider using ARC to avoid these problems.

于 2012-04-12T18:04:20.927 回答