【问题标题】:Objective-C NSMutableString CopyingObjective-C NSMutableString 复制
【发布时间】:2011-07-07 23:55:49
【问题描述】:

我在解释我最初的问题时做得很糟糕,所以这里是第二个刺。从自上而下的角度来看,目标如下:

我有一个使用 DDXML 解析和加载 XML 地图文件的地图类。这个地图文件有几个字符串供一个字符显示给玩家,我正在解析并存储在地图类中(作为 NSMutableString*)。当一个事件触发将其中一条消息加载给玩家时,游戏循环会抓取该 NSMutableString*,将其复制到一个临时的中间人对象中,然后在更新时最终将其传递给它的渲染对象。看起来很疯狂,但是如果你看到完整的代码集就会很有意义(哈,我希望!)。

我遇到了似乎是内存覆盖的情况......当我尝试在第二次或第三次传递中访问 NSMutableString 时(临时中间人或渲染对象),纹理坐标得到傻傻的。似乎琴弦本身完好无损,但附近的记忆似乎已被淹没。在渲染之前完成这些读取的同一个游戏循环迭代中,我偶尔会遇到崩溃(EXC_BAD_ADDR 或类似情况)。

我认为这几乎可以肯定是由于我(仍然)对 NSMutableStrings 的掌握不佳。顺便说一句,我正在使用可变版本,因为我需要在加载字符串后编辑字符串(例如添加 \n 字符)。这里有一些相关的代码 sn-ps 可能有助于更好地解释我在做什么:

我有一个用于渲染的 TextSnippet 结构,看起来类似于以下内容(为简洁起见,省略了一些数据):

struct TextSnippet
{
    NSMutableString* string;
}

我读取地图 (DDXML) 并将文本消息存储到地图对象中:(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];

然后我执行以下操作(注意:这可能真的很愚蠢和错误,我很肯定我正在泄漏内存,就像没有人的事,但我只是在快速尝试更糟糕的想法,这是最新的最差):

这是中间人层:

// 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* 数据更改为硬编码的 @"" 字符串常量时,内存问题就不存在了。我在这里处理字符串的方式难道不是一个问题吗?

再次感谢试图提供帮助的原始发帖者 - 我希望这能提供更多信息。

【问题讨论】:

  • 你提到的这个 NSMutableArray 在哪里?为什么要在结构中的数组中存储对象而不是仅使用 NSArray?
  • 什么内存被覆盖了?
  • 这些字符串首先需要是可变的吗?
  • Chuck,很好 - Array 评论是一个错字。我已经编辑了原始问题以反映。这里只是字符串。大多数功能代码都是在 C++ 中完成的,与平台无关,所以我尽量避免使用 Objective-C 类。也就是说,我必须使用 NSStrings(最好是 Mutables,因为我在这里或那里做了一些小的编辑)。被覆盖的内存在几个地方,但在这种情况下,它位于纹理坐标中,与我们复制到(而不是从)的字符串存储在相同的结构中。

标签: objective-c nsstring nsmutablestring


【解决方案1】:

我不知道您为什么会收到此错误(我从未遇到过),但您的示例代码中有一些看起来很奇怪的位(可能只是我缺乏 C/C++ 知识:-)

message->text[i++] = [[NSMutableString alloc] 
                        initWithString:[[text attributeForName:@"text"] stringValue]];

我在 SDK 中找不到对 stringValue 方法的任何引用。但除此之外,为什么不存储对正在创建的 NSMutableString 的引用呢?我也不确定text 是什么,但假设 `[text attributeForName:@"text"]' 返回一个 NSString,我认为您无论如何都不需要获取 stringValue。

m_msgText->string = [[NSMutableString alloc] 
                        initWithString:[m_message->text[m_currentText] mutableCopy]];

我不确定您为什么要使用 [m_message-&gt;text[m_currentText] mutableCopy] 位。为什么不干呢

 m_msgText->string = [[NSMutableString alloc] 
                        initWithString:[m_message->text[m_currentText]]];

因为它将通过从[m_message-&gt;text[m_currentText]] 复制文本来创建一个新的 NSMutableString。

请随意告诉我我在说垃圾,因为您可能比我更了解混合 C/C++ 和 Objective C :-)

【讨论】:

  • 您可以将最后一位缩减为m_msgText-&gt;string = [m_message-&gt;text[m_currentText] mutableCopy];-stringValue 可能会返回一个不可变的字符串,所以同样的事情也适用于那里。
  • Derek 和 Georg,我打赌你们都是对的……我不知道 NSMutableString 复制的行为,所以我认为这会起作用。让我做更多的挖掘,我会尽快发布我的结果。
  • Derek 和 Georg,我重写了我的问题......我希望这能更好地解释我想要完成的工作。我整天都在修补它,但我仍然没有太多运气。任何想法将不胜感激!
  • 这个答案很好,所以我接受了。事实证明,我处理 NSStrings 相当好,只是 Derek 的解决方案确实解决了一些小问题。内存覆盖是(鼓声!)一个完全不相关的问题,但清理我的字符串内存是值得花时间的。再次感谢!
猜你喜欢
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 2011-07-31
  • 1970-01-01
  • 2011-06-27
  • 2011-09-23
相关资源
最近更新 更多