0

以下は私のコードです(いくつかの無関係なものは省略されています):

@implementation HomeSceneController

...
@synthesize options = _options;    // _options is a NSArray object with 4 elements

- (id)init
{
    if (self = [super initWithNibName:@"HomeScene" bundle:nil]) {
        _currentOptionIndex = 0;

        // Following code add two key event observations, when up arrow or down arrow key is pressed, the corresponding function will be fired.
        [self addObservation:_KEY_UPARROW_ selector:@selector(UpArrowPressHandler)];
        [self addObservation:_KEY_DOWNARROW_ selector:@selector(DownArrowPressHandler)];

    }

    return self;
}

- (void)loadView {
    [super loadView];
    // init _options
    _options = [NSArray arrayWithObjects:
                _localGameOption,
                _networkGameOption,
                _controlSettingOption,
                _quitOption,
                nil];
    [self selectOption:_localGameOption];
}

....

// in these two functions, _options become nil! I don't know why...
- (void)UpArrowPressHandler {
    if (_currentOptionIndex > 0) {
        [self deselectOption:_options[_currentOptionIndex]];
        _currentOptionIndex--;
        [self selectOption:_options[_currentOptionIndex]];
    }
}

- (void)DownArrowPressHandler {
    if (_currentOptionIndex < 3) {
        [self deselectOption:_options[_currentOptionIndex]];
        _currentOptionIndex++;
        [self selectOption:_options[_currentOptionIndex]];
    }
}

@end

上矢印キーを押すと、UpArrowPressHandler関数が起動します。ただし、問題は、_options配列がnilになることです。

誰かがそれを修正する理由と方法を教えてもらえますか?

//===========================================================================================

追加の問題:

次のプログラムでは:

import "Deep.h"

@implementation Deep

- (id)init {
    if (self = [super init]) {
        _name = @"Deep";
    }
    return self;
}

- (void)test {
    NSLog(_name);
}

@end

テストメソッドは、別の場所で呼び出すと「Deep」を正しく出力できます。

ただし、@ ATaylorの説明によると、_nameはリリースする必要があります。

それで、私の問題はどこにありますか?

4

1 に答える 1

0

これは、_optionsに自動解放されたオブジェクトが割り当てられているためです。このオブジェクトは、呼び出されたメソッドを離れると解放されます。

それを「self.options」に割り当ててみてください。これにより、(ほとんどの場合)オブジェクトで「retain」が呼び出されるか、「retain」が明示的に呼び出されます。

もう一度コードで:次のいずれかを使用します。

self.options = [NSArray ...];

または:

_options = [[NSArray ...] retain];

完了したら、次のいずれかの方法で「オプション」をリリースすることを忘れないでください。

self.options = nil;

また:

[_options release];

これらのオプションの1つだけを選択してください。そうしないと、保持カウントで奇妙な動作が発生します。

ご覧のとおり、Appleは、自動リリースされたオブジェクトを返す「便利な機能」をいくつか提供しています。つまり、リリースを気にする必要はありません。一般的な経験則として:自分で呼び出すすべての割り当て/保持に対してリリースを呼び出します。

2番目の質問に答えるには:

_name = @"Deep";

変数への代入であり、'const char * _name ="Deep";'と同等です。Cから。単純な理由で、作成または保持しなかったものをリリースする必要はありません。(新規、割り当て、保持、コピーはありません)。変数が自動解放されるようなメソッドを呼び出さなかったため、オブジェクトも自動解放されません。

また、正確な問題を扱っているこの回答を参照してください。

明確にするために、文字列を取得するには、3つのタイプのメソッドがあります。

NSString *someString;
someString = @"MyString"; //No retain, no release, static String.
someString = [NSString stringWithFormat...]; //Autoreleased object, disappears after the method expires.
someString = [[NSString alloc] initWithFormat...]; //Alloced object, must be released.
于 2012-08-06T11:29:16.337 に答える