Нуб озадачен поведением массива NSMutable

Я нуб, пытаюсь разобраться с использованием XCode, чтобы собрать очень простой интерфейс для очень простого приложения для Mac.

Я максимально упростил свое приложение, чтобы проиллюстрировать загвоздку, с которой столкнулся.

Мой текущий интерфейс состоит из одной кнопки.

В моем файле AppController.h у меня есть следующее:

    @interface AppController : NSObject 
    {
        NSMutableArray *ages;
        int price;
        NSString *culler;
    }
    -(IBAction) handleButtonClick: (NSButton*)sender;

    @end

и в моем файле AppController.m я использую свой метод awakeFromNib для установки начальных значений:

    -(void)awakeFromNib
    {
        ages = [NSMutableArray arrayWithObjects: nil];
        [ages addObject: [NSNumber numberWithInt: 10]];
        [ages addObject: [NSNumber numberWithInt: 21]];

        price = 45;

        culler = [NSString stringWithString: @"bright green"];

        NSLog(@"waking up from nib, ages contains %i objects",[ages count]);
        NSLog(@"they are ...");
        for(int i = 0; i<[ages count]; i++)
        {
                NSLog(@"%i", [[ages objectAtIndex: i] integerValue]);
        }   

        NSLog(@"waking up from nib, the current price is %i", price);   
        NSLog(@"waking up from nib, the color is %@", culler);      

    }

Кажется, все работает нормально, и я получаю ожидаемые сообщения журнала.

Но в моем методе обработки нажатия на мою единственную кнопку у меня есть следующее:

-(void) handleButtonClick: (NSButton*) sender
{
    NSLog(@"you clicked the button");
    NSLog(@"after clicking the button, the current price is %i", price);
    NSLog(@"after clicking the button, the color is %@", culler);   

    NSLog(@"after clicking the button, ages contains %i objects",[ages count]);
    NSLog(@"they are ...");
    for(int i = 0; i<[ages count]; i++)
    {
            NSLog(@"%i", [[ages objectAtIndex: i] integerValue]);
    }   

}

Когда я нажимаю кнопку, я получаю сообщения журнала, говорящие мне, что «выбраковка» и «цены» содержат именно то, что я ожидаю (= точно те значения, которые я дал им в «awakeFromNib»), но затем программа выдает «Программа получила сигнал : «EXC_BAD_ACCESS»», и пляжный мяч выглядит так, как будто ему не нравится, что я ссылаюсь на свой массив «возраст».

Очевидно, здесь есть что-то фундаментальное, чего я не понимаю. Я могу ссылаться на свой int и свой NSString, но не могу ссылаться на свой NSMutableArray?

Я сбит с толку.

Если бы кто-нибудь мог указать мне в правильном направлении, я был бы очень благодарен.

Спасибо за чтение этого.


person Sam Pollard    schedule 27.07.2011    source источник
comment
почему бы не скопировать сюда код вместо скриншотов?   -  person Vladimir    schedule 27.07.2011
comment
Вы правы - я должен был использовать код. Впервые на форуме - запутался с доступными опциями.   -  person Sam Pollard    schedule 27.07.2011


Ответы (3)


Вы инициализируете свой массив с помощью arrayWithObjects. Обратите внимание, что эти методы возвращают объект autoreleased, который, вероятно, недействителен после окончания awakeFromNib.

Либо добавьте retain сообщение:

ages = [[NSMutableArray arrayWithObjects:nil] retain];

Или используйте метод, который не возвращает объект autoreleased, например способ по умолчанию alloc и init:

ages = [[NSMutableArray alloc] initWithObjects:nil];

И обязательно прочитайте Руководство по управлению памятью< /а>.

person sidyll    schedule 27.07.2011
comment
Отлично. Большое спасибо, что нашли время помочь нубу. Очень признателен. Теперь работает нормально. - person Sam Pollard; 27.07.2011
comment
Рад, что Сэм работает, и добро пожаловать в StackOverflow! Кроме того, не забудьте отметить ответ как принятый, нажав на галочку под подсчетом голосов. Таким образом, вы также можете помочь будущим читателям, найдя решение проблемы. - person sidyll; 27.07.2011
comment
В 9 случаях из 10 пляжный мяч возникает именно из-за этого. С самого начала выработайте хорошие привычки управления памятью, и вы станете счастливым программистом! - person Alec Sloman; 28.07.2011

Мне кажется, что вы не сохранили ages. Так что это "пуф", когда код "появляется в эфире" в презентации пользовательского интерфейса.

Вам нужно изучить управление хранилищем в Objective-C.

person Hot Licks    schedule 27.07.2011
comment
Спасибо. Управление хранилищем только что переместилось в начало моего списка «вещей для изучения». - person Sam Pollard; 27.07.2011

Вам нужно сохранить свой массив при его создании, иначе он будет уничтожен в конце текущего цикла событий. Вы также можете использовать создание стиля [[alloc] init], которое не обязательно требует сохранения.

person kfrymire_noggin    schedule 27.07.2011