Objective-C NSMutableString Copying
I did a poor job of explaining my original question, so here's a second stab. From a top down perspective, here's the goal:
I have a map class that is using DDXML to parse and load in an XML map file. This map file has several strings for a character to display to the player, which I am parsing and storing in the map class (as NSMutableString*). When an event triggers to load one of those messages to the player, the game loop grabs that NSMutableString*, copies it into a temporary middle-man object, which then when updates passes it finally into its rendering object. It seems crazy, but it makes a lot of sense if you see the full set of code (hah, I hope!).
I'm experiencing what SEEMS to be 开发者_如何转开发a memory overwrite situation... when I try to access the NSMutableString in the second or third pass (either to the temp middle-man or to the rendering object), the texture coordinates get goofy. It seems like the strings themselves are intact, but nearby memory looks hosed. I will occasionally get crashes (EXC_BAD_ADDR, or similar) in the same game loop iteration that these reads are done right before rendering.
I think this is almost certainly due to my (still) poor grasp of NSMutableStrings. By the by, I am using the mutable version as I need to edit the strings (add \n characters, for example) after they have been loaded. Here's some relevant code snippets that may help better explain what I'm doing:
I have a TextSnippet structure used for rendering that looks similar to the following (some data omitted for brevity):
struct TextSnippet
{
NSMutableString* string;
}
I read the map (DDXML) and store the text messages into the map object with: (message->text is defined as NSMutableString* text[MAX_TEXT_PER_MESSAGE];
message->text[i] = [NSMutableString stringWithCapacity:50];
[message->text[i] setString:[[text attributeForName:@"text"] stringValue]];
[message->text[i] retain];
I then do the following (note: this could be really stupid and wrong, and I'm positive I'm leaking memory like nobody's business, but I'm just trying rapidly worse ideas, and this is the latest of the worst):
This is the middle-man tier:
// Properly copy the NSMutableString into the local message
for (int i = 0; i < m_message->count; i++)
{
m_message->text[i] = [message->text[i] mutableCopy];
[message->text[i] retain];
}
Finally, later in the loop I actually write to the TextSnippet structure (m_msgText in this case), so the text can be rendered:
m_msgText->string = [m_message->text[m_currentText] mutableCopy];
[m_msgText->string retain];
Like I said, I know it's kind of nasty doing the extra copies... I'm looking into other, much more extensive rewrites to get around this, but in the interim... how SHOULD you go about doing this, if you did need to pass a NSMutableString* around so much? I suppose the problem still COULD be something else, but whenever I change the NSMutableString* data to hard-coded @"" string constants at the middle-man tier, the memory problem is not present. Doesn't it just about have to be a problem with how I'm handling my strings here?
Thanks again to the original posters who tried to offer some help - I hope this is more informative.
I don't know why you are getting this error (I've never had one), but there is some bits in your sample code that look odd (may be just my lack of C/C++ knowledge :-)
message->text[i++] = [[NSMutableString alloc]
initWithString:[[text attributeForName:@"text"] stringValue]];
I can't find any reference to a stringValue
method in the SDK. But aside from that, why not just store a reference to the NSMutableString being created? I'm also not sure what text
is, but presuming that `[text attributeForName:@"text"]' returns a NSString, I don't think you need to get the stringValue anyway.
m_msgText->string = [[NSMutableString alloc]
initWithString:[m_message->text[m_currentText] mutableCopy]];
I'm not sure why you are doing the [m_message->text[m_currentText] mutableCopy]
bit. Why not just do
m_msgText->string = [[NSMutableString alloc]
initWithString:[m_message->text[m_currentText]]];
becuase it will create a new NSMutableString by copying the text from [m_message->text[m_currentText]]
.
Feel free to tell me I'm talking rubbish because you probably know more about mixing C/C++ and Objective C than I do :-)
精彩评论