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

请只选择其中一个选项,否则您会在保留计数方面出现奇怪的行为。

你看,Apple 为我们提供了许多“便利功能”,它们返回自动释放的对象,这意味着我们不必为它们的释放而烦恼。作为一般经验法则:为您自己调用的每个分配/保留调用释放。

回答第二个问题:

_name = @"Deep";

是对变量的赋值,相当于'const char *_name = "Deep";' 来自 C。没有必要释放它,原因很简单,你没有创建或保留它。(没有新的,没有分配,没有保留,没有复制)。该对象也不会自动释放,因为您没有调用任何类型的方法,这会导致变量被自动释放。

另外,请参阅this answer,它处理确切的问题。

只是为了澄清,要获得一个字符串,有三种类型的方法。

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 回答