Проблемы с makeObjectsPerformSelector внутри и снаружи класса? - PullRequest
0 голосов
/ 27 апреля 2010

Мы с другом создаем карточную игру для iPhone, и в эти первые дни проекта я разрабатываю класс Deck и класс Card, чтобы не отставать от карт. Я хочу протестировать метод shuffle класса Deck, но я не могу показать значения карт в экземпляре класса Deck. Класс Deck имеет объекты NSArray of Card, которые имеют метод displayCard, который показывает значение и соответствие с использованием вывода консоли (printf или NSLog). Чтобы показать, какие карты находятся в экземпляре колоды, я использую это, [deck makeObjectsPerformSelector:@selector(displayCard)], где колода - это NSArray в классе колоды. Внутри класса Deck на выводе консоли ничего не отображается. Но в тестовом файле это работает просто отлично. Вот тестовый файл, который создает свой собственный NSArray:

#import <Foundation/Foundation.h>
#import "card.h"

int main (int argc, char** argv)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    Card* two = [[Card alloc] initValue:2 withSuit:'d'];
    Card* three = [[Card alloc] initValue:3 withSuit:'h'];
    Card* four = [[Card alloc] initValue:4 withSuit:'c'];
    NSArray* deck = [NSArray arrayWithObjects:two,three,four,nil];

    //Ok, what if we release the objects in the array before they're used?
    //I don't think this will work...
    [two release];
    [three release];
    [four release];
    //Ok, it works... I wonder how...

    //Hmm... how will this work?
    [deck makeObjectsPerformSelector:@selector(displayCard)];
    //Yay! It works fine!

    [pool release];

    return 0;
}

Это прекрасно работает, поэтому я создал инициализатор для этой идеи, создавая 52 объекта карты по одному и добавляя их в NSArray, используя deck = [deck arrayByAddingObject:newCard]. Это реальная проблема с тем, как я использую makeObjectsPerformSelector или что-то до / после него?

Ответы [ 2 ]

1 голос
/ 27 апреля 2010

Когда вы добавляете объекты в массив, он увеличивает значение retainCount на единицу. Вот почему его освобождение не освобождает объект. Массив создается в состоянии автоматического освобождения. Когда вы освобождаете пул, он освобождает массив и все объекты. Вы должны понимать, что релиз не равен бесплатному. Это просто уменьшает retainCount. Только когда retainCount обращается в ноль, он освобождается. поэтому вне вашей функции вы должны каким-то образом сохранить объект.

0 голосов
/ 27 апреля 2010

Если вы хотите увидеть счет сохранения в реальном времени и в действии, позвоните что-то вроде:

int main (int argc, char** argv)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    Card* two = [[Card alloc] initValue:2 withSuit:'d'];
    NSLog(@"Current retain count for the '2' Card: %ud", [two retainCount]);

    Card* three = [[Card alloc] initValue:3 withSuit:'h'];
    Card* four = [[Card alloc] initValue:4 withSuit:'c'];
    NSArray* deck = [NSArray arrayWithObjects:two,three,four,nil];

    NSLog(@"Current retain count for the '2' Card after array retains it: %ud", [two retainCount]);

    [two release];
    [three release];
    [four release];

    NSLog(@"Current retain count for the '2' Card after releasing instance: %ud", [two retainCount]);

    [deck makeObjectsPerformSelector:@selector(displayCard)];

    [deck release];
    NSLog(@"Current retain count for the '2' Card after releasing instances within 'deck' array: %ud", [two retainCount]);

    [pool release];

    return 0;
}
...