Никаких значений в экземплярах объектов после того, как я добавлю их в NSMutableArray - PullRequest
1 голос
/ 16 декабря 2010

Я добавляю объект с двумя экземплярами NSString в NSMutableArray.Операторы журнала говорят мне, что переменные установлены правильно, но после того, как я добавлю их в массив, они, кажется, перезаписываются или позже, вообще не отображаются.Это сводит меня с ума.Я подозреваю, что это проблема с mgmt памяти ...

Извините за длинный вывод, но я отчаянно ...

Я вызываю этот метод, когда нажимаю кнопку, и он принимает текстиз текстового представления затем я вызываю другой метод из пункта меню, и у меня есть лог-операторы для итерации по массиву, чтобы проверить значения экземпляров vars (вопрос, ответ), и оба они пусты в каждом объекте Flashcard, сохраненном в массиве...

- (IBAction)nextCard:(id)sender
{
    int i = 0;
    NSLog(@"> Clicked \"Next Card\" button");
    NSLog(@"Called method: -(IBAction)nextCard:");

    NSString *questionString = [[questionView textStorage] string];
    NSString *answerString = [[answerView textStorage] string];

    /* Make sure we get input in both fields, otherwise do nothing */
    /* Todo: use a regexp lib to make this more robust */
    NSString *questionWithoutWhitespace = [questionString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    NSString *answerWithoutWhitespace = [answerString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

    NSLog(@"   questionString: %@", questionString);
    NSLog(@"   answerString: %@", answerString);

    if ( ([questionWithoutWhitespace length] != 0) && ([answerWithoutWhitespace length] != 0) )
    {
        Flashcard *flashcard = [Flashcard newCardWithQuestion:questionString andAnswer:answerString];


        NSLog(@"   Flashcard->question: %@", [flashcard getQuestion]);
        NSLog(@"   Flashcard->answer: %@", [flashcard getAnswer]);


        [cardList addObject:flashcard];

        NSLog (@"   [cardList count]: %d", [cardList count]);   
        NSLog(@"     FlashCard %i, question: %@", i, [[cardList objectAtIndex:i] getQuestion]);
        NSLog(@"     FlashCard %i, answer: %@", i, [[cardList objectAtIndex:i] getAnswer]);
        i++;

        [self clearCard];
    }
}

Вот вывод после того, как я несколько раз его назвал:

[Session started at 2010-12-15 22:27:21 -0800.]
Called -(void)awakeFromNib
> Clicked "Next Card" button
Called method: -(IBAction)nextCard:
questionString: q1
answerString: a1
Flashcard->question: q1
Flashcard->answer: a1
[cardList count]: 1
FlashCard 0, question: q1
FlashCard 0, answer: a1
Called Method: -(void)clearCard

> Clicked "Next Card" button
Called method: -(IBAction)nextCard:
questionString: q2
answerString: a2
Flashcard->question: q2
Flashcard->answer: a2
[cardList count]: 2
FlashCard 0, question: q2
FlashCard 0, answer: a2
Called Method: -(void)clearCard


> Selected "File -> New" menu option
Called method: -(IBAction)newCardSet:
 cardList: 
 [cardList count]: 2
    Element 0 = <Flashcard: 0x480570>
      FlashCard 0, question: 
      FlashCard 0, answer: 
    Element 1 = <Flashcard: 0x473b70>
FlashCard 1, question: 
FlashCard 1, answer: 

Ответы [ 2 ]

1 голос
/ 16 декабря 2010

Проблема в этих двух строках:

NSString *questionString = [[questionView textStorage] string];
NSString *answerString = [[answerView textStorage] string];

Метод string происходит от NSAttributedString .Документы говорят это:

Из соображений производительности этот метод возвращает текущее резервное хранилище приписанного строкового объекта.Если вы хотите сохранить моментальный снимок этого при манипулировании возвращенной строкой, вы должны сделать копию соответствующей подстроки.

Поэтому вам необходимо заменить две строки на:

NSString *questionString = [[[[questionView textStorage] string] copy] autorelease];
NSString *answerString = [[[[answerView textStorage] string] copy] autorelease];

Это связано с тем, что NSTextStorage - это ann NSMutableAttributedString, и когда для него задано пустое значение, полученная вами строка очищается.


Не относится, но вы можете установить i на [cardList count]в начале вместо 0.

Также ожидается, что методы, начинающиеся с new, будут возвращать ваш собственный объект в соответствии с правилами управления памятью .Если newCardWithQuestion:andAnswer: соответствует правилам, ваш код протекает.Если нет, вам следует переименовать метод, возможно, опустив слово «новый».

0 голосов
/ 16 декабря 2010

Мое предположение основано исключительно на том, что вы здесь показали: две строки не являются retain 'd или copy' d, когда вы создаете здесь FlashCard объект:

Flashcard *flashcard = [Flashcard newCardWithQuestion:questionString andAnswer:answerString];

Как выглядит этот метод? В какой-то момент в этом методе, если эти две строки являются переменными экземпляра, они должны быть сохранены или скопированы в ваш экземпляр flashcard.


Кроме того, и это не имеет отношения к вашей проблеме, но при работе с Какао вы склонны называть свои вспомогательные методы - (void)key вместо - (void)getKey, где key обычно является именем переменной вашего экземпляра.

Мало того, что это соглашение, но оно также позволяет вам делать действительно полезные вещи с Runtime, и если вы используете объявленные свойства, эти методы созданы для вас. Проверьте кодирование значения ключа, если вы хотите узнать больше. Действительно фантастические вещи построены сверху этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...