Objective-C NSMutableString 复制
我没有很好地解释我最初的问题,所以这是第二次尝试。从自上而下的角度来看,目标是:
我有一个地图类,它使用 DDXML 来解析并加载 XML 地图文件。该地图文件有几个用于向玩家显示字符的字符串,我正在解析这些字符串并将其存储在地图类中(作为 NSMutableString*)。当事件触发将这些消息之一加载到玩家时,游戏循环会获取 NSMutableString*,将其复制到临时中间人对象中,然后在更新时将其最终传递到其渲染对象中。这看起来很疯狂,但是如果您看到完整的代码集,就会很有意义(哈哈,我希望!)。
我正在经历似乎是内存覆盖的情况......当我尝试在第二或第三遍中访问 NSMutableString (无论是临时中间人还是渲染对象)时,纹理坐标变得愚蠢。弦本身似乎完好无损,但附近的记忆看起来已经被破坏了。在渲染之前完成这些读取的同一游戏循环迭代中,我偶尔会遇到崩溃(EXC_BAD_ADDR 或类似情况)。
我认为这几乎肯定是由于我(仍然)对 NSMutableStrings 掌握不好。顺便说一句,我正在使用可变版本,因为我需要在加载字符串后对其进行编辑(例如添加 \n 字符)。以下是一些相关的代码片段,可能有助于更好地解释我正在做的事情:
我有一个用于渲染的 TextSnippet 结构,看起来类似于以下内容(为简洁起见,省略了一些数据):
struct TextSnippet
{
NSMutableString* string;
}
我读取地图 (DDXML) 并存储文本消息进入地图对象:(message->text被定义为 NSMutableString* text[MAX_TEXT_PER_MESSAGE];
message->text[i] = [NSMutableString stringWithCapacity:50];
[message->text[i] setString:[[text attributeForName:@"text"] stringValue]];
[message->text[i] retain];
然后我执行以下操作(注意:这可能非常愚蠢和错误,并且我确信我正在像任何人一样泄漏内存,但我只是在快速尝试更糟糕的想法,这是最糟糕的最新的):
这是中间人层:
// 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];
}
最后,在循环的后面我实际上写了到 TextSnippet 结构(在本例中为 m_msgText),以便可以呈现文本:
m_msgText->string = [m_message->text[m_currentText] mutableCopy];
[m_msgText->string retain];
就像我说的,我知道做额外的副本有点令人讨厌......我正在研究其他更广泛的重写来解决这个问题, 但在此期间...如果您确实需要传递 NSMutableString* 这么多,您应该如何做呢?我想问题仍然可能是其他问题,但每当我将 NSMutableString* 数据更改为硬编码@ "" 字符串常量位于中间层,不存在内存问题。这难道不是我处理琴弦的方式有问题吗?
再次感谢试图提供一些帮助的原始发帖者 - 我希望这能提供更多信息。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不知道为什么你会收到这个错误(我从来没有遇到过),但你的示例代码中有一些看起来很奇怪的位(可能只是我缺乏 C/C++ 知识:-)
我不能在 SDK 中查找对
stringValue
方法的任何引用。但除此之外,为什么不只存储对正在创建的 NSMutableString 的引用呢?我也不确定text
是什么,但假设 `[text attributeForName:@"text"]' 返回一个 NSString,我认为您无论如何都不需要获取 stringValue。我不确定您为什么要执行
[m_message->text[m_currentText] mutableCopy]
位。为什么不直接这样做,因为它会通过复制
[m_message->text[m_currentText]]
中的文本来创建一个新的 NSMutableString。请随意告诉我我在胡说八道,因为你可能比我更了解混合 C/C++ 和 Objective C :-)
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 :-)
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 whattext
is, but presuming that `[text attributeForName:@"text"]' returns a NSString, I don't think you need to get the stringValue anyway.I'm not sure why you are doing the
[m_message->text[m_currentText] mutableCopy]
bit. Why not just dobecuase 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 :-)