在将对象添加到NSMutableArray之后,对象的实例值没有值

问题描述:

我正在向两个NSString实例值添加一个对象到NSMutableArray。日志语句告诉我变量设置正确,但在将它们添加到数组后,它们似乎被覆盖或更晚,根本不显示。这让我疯狂。我怀疑它的内存MGMT问题...在将对象添加到NSMutableArray之后,对象的实例值没有值

对不起,长时间的输出,但我越来越绝望......

我把这种方法,当我点击一个按钮,它需要从文本一个TextView,然后我从菜单项中调用另一个方法,并且我有日志语句遍历数组以检查实例变量(问题,答案)的值,并且两个在保存在数组中的每个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: 

我的猜测仅仅基于你下面显示的那样:两个字符串没有被retain'd或copy倒是当您创建FlashCard对象的位置:

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

是什么方法看起来像?在该方法的某个点,如果这两个字符串是实例变量,则应将其保留或复制到您的实例flashcard


而且,这无关你的问题,但与可可打交道时,你会名称,而不是- (void)getKey,其中key通常是你的实例变量名的附件方法- (void)key

这不仅是这个约定,而且它还允许你在运行时做很有用的事情,如果你使用声明的属性,这些方法是为你创建的。如果您想了解更多信息,请查看Key-Value Coding。真正奇妙的东西是建立在它之上的。

+0

谢谢! +(id)newCardWithQuestion:(NSString *)question andAnswer:(NSString *)answer {id} newCard = [[self alloc] init]; [新卡设置问题:问题]; \t [newCard setAnswer:answer]; return [newCard autorelease]; } – user522034 2010-12-16 07:32:02

+0

另外,noob问题(我很快会RTFM的*,但你如何添加回报评论字段?) – user522034 2010-12-16 07:33:24

+0

成功! +(id)newCardWithQuestion:(NSString *)question andAnswer:(NSString *)answer {id} newCard = [[self alloc] init]; [新卡设置问题:[问题副本]]; \t [newCard setAnswer:[answer copy]]; return [newCard autorelease]; } – user522034 2010-12-16 07:50:22

的问题是在以下两行:

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是安NSMutableAttributedString并且当被设置为空,您收到的字符串被清空。


无关,但你可能想在开始,而不是0设置i[cardList count]

另外,根据memory management rules,预计将以new开头的方法返回您拥有的对象。如果newCardWithQuestion:andAnswer:符合规则,您的代码正在泄漏。如果没有,您应该重新命名该方法,可能是通过删除单词“new”。