views:

24

answers:

1

Hi everyone I am working on a game and I have run into a really weird issue and was hoping to get some help. Basically sometimes the text is a bit long to show in one textbox so I wanted it to break down a string and store the undisplayed text in a string to be used in the next message box. So when I use this code..

NSString * Talkin1 = @"Hello I am an annoying string";
NSString * Talkin2 = [Talkin1 substringToIndex:5];

It makes Talkin2 the value of Hello which is what I want. Then I store it in the object with..

[_window setMultiMessage:Talkin2];

which goes to my set and get methods in an object i made.

In it's interface...

 NSString * multiMessage;

in its .m

-(void) setMultiMessage:(NSString*)messageTwo
{
 multiMessage = messageTwo; 
}
-(NSString*) getMultiMessage
{
 return multiMessage;
}

then later the main object pulls it out again, when it is done closing the first window with...

 NSString * talking = [_window getMultiMessage];

Now in debugging, I have noticed talking's value will be "out of scope" when i get the string back from _window. So then it crashes my program when it tries to use it.

But. If i do this everything works fine.

NSString * Talkin1 = @"Hello I am an annoying string";
 //NSString * Talkin2 = [Talkin1 substringToIndex:5];

[_window setMultiMessage:Talkin1];

So it works perfect (except for splitting the string like I want) when I use @" " but not when I use any result of substringToIndex or substringFromIndex.

I am new to objective c so I assume it is something basic I am missing. Any help would be wonderful! Thank you in advance.

+4  A: 

(Assuming no GC.)

-substringToIndex: returns an autoreleased object. But you are not retaining the object in the setter, thus no one "owns" the Talkin2 and it will be deallocated "later". You need to copy or retain the string in the setter.

-(void) setMultiMessage:(NSString*)messageTwo {
  if (multiMessage != messageTwo) {
    [multiMessage release];
    multiMessage = [messageTwo retain];
  }  
}

Actually you should really use Objective-C 2.0's declared property feature. It allows correct setter and getter be generated automatically.

@interface  ....  { ... }
...
@property(copy) NSString* multiMessage;  // <--
...
@end

@implementation ....
@synthesize multiMessage;     // <--
...
@end

...

_window.multiMessage = Talkin2; 
// or: [_window setMultiMessage:Talkin2];

NSString* talking = _window.multiMessage;
// or: talking = [_window multiMessage];
KennyTM
Hi thank you, That fixes the issue, although I had to turn the if statement to multiMessage != messageTwo which is what I think you meant. Thank you very much again I was stuck on that for days.
Bagellad
@Bagellad: That's right, `multiMessage != messageTwo`. And that's why we should use declared properties :).
KennyTM
I will start using them believe me.
Bagellad