2

参考までに、私はすでに読んだ:

私はそれが役立つと思いました:)。

このアプリは教育ツールであり、人々が単純な遺伝学を視覚化するのを助けることを目的としています。変数名などが意味をなすように、いくつかの背景があります。アプリの実行時に実行されるメインコードは次のとおりです。

- (void)viewDidAppear:(BOOL)animated {
ThingzCore *core = [[ThingzCore alloc] init];

ThingzThing *thing1 = [[ThingzThing alloc] init];
thing1.breed = @"AB";
thing1.pattern = @"AC";
thing1.color = @"CA";
thing1.gender = @"XY";
thing1.generation = 1;
thing1.isEgg = NO;

ThingzThing *thing2 = [[ThingzThing alloc] init];
thing2.breed = @"CD";
thing2.pattern = @"BA";
thing2.color = @"CB";
thing2.gender = @"XX";
thing2.generation = 1;
thing2.isEgg = NO;

NSLog(@"Breeding GD BR PT CL G");

ThingzThing *child = [core mateFather:thing1 withMother:thing2];
NSLog(@"Round 1: %@ %@ %@ %@ %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);

child = [core mateFather:thing1 withMother:thing2];
NSLog(@"Round 2: %@ %@ %@ %@ %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);

child = [core mateFather:thing1 withMother:thing2];
NSLog(@"Round 3: %@ %@ %@ %@ %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);

child = [core mateFather:thing1 withMother:thing2];
NSLog(@"Round 4: %@ %@ %@ %@ %d",child.gender,child.breed,child.pattern,child.color,child.generation);
sleep(10);

[thing1 release];
[thing2 release];
[core release];
}

そして、これをさまざまな方法で実行するとどうなりますか?

  • ブレークポイントなしで実行すると、2番目のsleep()の後、「ラウンド3」NSLogの前に、コンソールメッセージなしでクラッシュします。
  • ブレークポイントを有効にして実行しますが、定義されていない場合は、シーケンス全体を実行します。4番目のsleep()の後、EXC_BAD_ACCESSでクラッシュします。
  • ブレークポイントを有効にしてNSZombiesEnabledで実行すると、上記と同じことを実行します。これ以上の情報はなく、EXC_BAD_ACCESSだけです。
  • Instrumentsで実行している場合、リークは表示されません。

これは、4回呼び出されるルーチンです。

-(ThingzThing *)mateFather:(ThingzThing *)father 
         withMother:(ThingzThing *)mother {
// will we be doing a mutation?
int mutationPercentage = father.generation + mother.generation;
int mutationNumber = (arc4random() % ((unsigned)100 + 1));
BOOL isMutation = NO;
if (mutationNumber <= mutationPercentage) {
    isMutation = YES;
}

// get possibilities
NSArray *possibilities = [self possibilitiesByMatingFather:father 
                                                withMother:mother 
                                                 mutations:isMutation];
// randomly select one of the possibilities
int keeping = (arc4random() % ((unsigned)[possibilities count]));
return [possibilities objectAtIndex:keeping];
}

コード全体を貼り付けないと、possiblesByMatingFather:withMother:mutations関数はNSMutableArrayを返します。そのルーチンは、以下を使用して配列を宣言します。

NSMutableArray *possibilities = [NSMutableArray array];

それから:

return possibilities;

可能性に対してリリースまたは自動リリースメッセージを送信しません。私の理解では、私が持っている方法で配列を作成することは、暗黙の自動解放です。配列を返すので、配列を割り当てたくありませんでした。そのため、明示的に解放する機会がありませんでした。

可能性NSMutableArrayに保持されているオブジェクトは、カスタムクラスです。それらは次のように追加されます。

ThingzThing *newThing = [[ThingzThing alloc] init];
newThing.breed = choiceBreed;
newThing.gender = choiceGender;
newThing.color = choiceColor;
newThing.pattern = choicePattern;
newThing.generation = mother.generation + father.generation;
newThing.name = @"";
newThing.isEgg = YES;
[possibilities addObject:newThing];
[newThing release];

これはほとんどの場合うまくいくようです。少なくとも、ブレークポイントが有効になっている場合、プログラムは、上記のように、最後まで文句なしにコードを実行します。

ここで、私が間違っていることについて何か提案はありますか?明らかにある種のメモリ管理の問題ですが、頭の中で分類することはできません。

ところで、無駄に、壁に物を投げてそれを理解しようとして、私はメインルーチンから1行を次のように変更しました:

// get possibilities
NSArray *possibilities = [[self possibilitiesByMatingFather:father 
                                                withMother:mother 
                                                 mutations:isMutation] retain];

無駄に。同じ結果。したがって、問題は、possiblesByMatingFather:withMother:mutationsによって返される配列を保持することではありません。そのリターンを保持することを強制することは役に立ちません。

4

3 に答える 3

1

多くの場合、このタイプの状況では、アプリが停止したときに実際のエラーがデバッガーに表示される場所にありません。

たとえば、デバッガーがメソッド呼び出しを指している場合でも、問題は実際にはメソッド内で発生します。メソッドが呼び出されたときではありません。

追跡するには、エラーをトリガーするメソッド呼び出しの直前にブレークポイントを設定することをお勧めします。この場合、これはmateFather:withMother:呼び出しになります。次に、その方法にステップインします。問題がそのメソッド内で発生する、またはそのメソッド内から呼び出されるメソッド内でさえ発生する可能性があります。

于 2010-10-05T17:48:48.543 に答える
0

ThingzThingクラスの文字列プロパティのプロパティ宣言が正しいことを確認してください。

例えば

@property (nonatomic, retain) NSString* breed;

保持またはコピーする必要があります割り当てないでください...

于 2010-10-05T18:40:08.013 に答える
0

それを見つけた。8つのメソッド呼び出しを埋めて、明らかに自動解放されたNSArrayにリリースを送信していました。最初の呼び出しルーチン(viewDidAppear)が自動解放モードに落ちると、すでに解放されたオブジェクトを自動解放しようとし、爆発しました。良い悲しみ-XCodeがそれを追跡するのを助けることができた方法はありますか?

いずれにせよ、誰かがこれに遭遇した場合に備えて、自分で明示的に割り当てていないものにリリースメッセージを送信していないことを確認してください。割り当てなかった場合は、それ自体が自動リリースであり、リリースを送信すると保持カウントが負になり、FoundationフレームワークがEXC_BAD_ACCESSで嘔吐する可能性があります。

于 2010-10-06T03:05:06.710 に答える