使用选择器时NSArray变为无效

时间:2012-08-06 11:23:48

标签: objective-c cocoa

以下是我的代码(省略了一些不相关的东西):

@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数组变为零。

有谁能告诉我为什么以及如何解决它?

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

其他问题:

在以下程序中:

import "Deep.h"

@implementation Deep

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

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

@end

当我在其他地方打电话时,测试方法可以正确打印“深度”。

然而,根据@ ATaylor的解释,_name应该被释放。

那么,我的问题在哪里?

1 个答案:

答案 0 :(得分:0)

那是因为_options被分配了一个自动释放的对象,一旦你离开调用它的方法就会被释放。

尝试将其分配给'self.options',这将(很可能)在对象上调用'retain',或明确调用'retain'。

再次使用代码: 使用:

self.options = [NSArray ...];

或者:

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

一旦完成,请不要忘记发布“选项”,或者通过以下方式发布:

self.options = nil;

或:

[_options release];

请只选择其中一个选项,否则你会因保留计数而产生奇怪的行为。

你知道,Apple为我们提供了许多“便利功能”,它们可以返回自动释放的对象,这意味着我们不必为他们的发布而烦恼。 一般的经验法则是: 为您自己调用的每个alloc / retain调用release。

回答第二个问题:

_name = @"Deep";

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

此外,请参阅this回答,其中涉及确切的问题。

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

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.