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];

私のゲームクラスでは、これは初期化方法です。

-(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;
}

これで、フリーズし続ける方法はGameにあります。これは、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];
    

    あなたが割り当てるときはいつでも、あなたがその責任を他の誰かに渡さない限り、あなたはおそらく解放する必要があります。ドキュメントを読むと、addObjectretainと呼ばれていることがわかります。そのため、リリースの責任を負いませんでした。この場合、numberWithIntは自動解放されたオブジェクトを返します。

  5. このコード

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

    すぐに最初のアレイをリークします。正方形を1つの配列オブジェクトに設定してから、まったく異なるものに設定します。最初のものへの参照は失われます。最初の行を削除する必要があります(同様にfinishを使用します)。

これが新しいプロジェクトの場合は、すぐに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

まず、ファーストクラスの実装でlevelStart配列とlevelFinish配列をリリースしたことがありますか?その場合、2番目のクラスをインスタンス化した後、これらのオブジェクトを保持しないため、これは明らかな問題です。私の提案は、プロパティを使用して配列を2番目のクラスに保持することです。何かのようなもの

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

あなたの宣言の後に:

@synthesize squares, finish;

.mファイルで、最後にイニシャライザで次のように割り当てます。

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

これで、新しいクラスにコピーが保持されます。また、私は使用を検討します:

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

読みやすさを向上させます。また、これらの問題を回避するためにARCの使用を検討します。

于 2012-04-12T18:04:20.927 に答える