Objective-C NSMutableString Копирование - PullRequest
1 голос
/ 08 июля 2011

Я плохо объяснил свой первоначальный вопрос, так что вот второй удар.С точки зрения сверху вниз, вот цель:

У меня есть класс карты, который использует 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 * на жестко закодированные @ "" строковые константы на уровне среднего уровня, проблема с памятью не возникает.Разве это не должно быть проблемой из-за того, как я здесь работаю со строками?

Еще раз спасибо оригинальным постерам, которые пытались предложить некоторую помощь - надеюсь, это более информативно.

1 Ответ

0 голосов
/ 08 июля 2011

Я не знаю, почему вы получаете эту ошибку (у меня ее никогда не было), но в вашем примере кода есть некоторые кусочки, которые выглядят странно (возможно, это просто мое отсутствие знаний C / C ++: -)

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

Я не могу найти ссылку на метод stringValue в SDK.Но кроме этого, почему бы просто не сохранить ссылку на создаваемую строку NSMutableString?Я также не уверен, что такое text, но предполагая, что `[text attributeForName: @" text "] 'возвращает строку NSString, я не думаю, что вам все равно нужно получить stringValue.

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

Я не уверен, почему вы делаете бит [m_message->text[m_currentText] mutableCopy].Почему бы просто не сделать

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

, потому что он создаст новую NSMutableString, скопировав текст из [m_message->text[m_currentText]].

Не стесняйтесь сказать, что я говорю мусор, потому что вы, вероятно, знаете большео смешивании C / C ++ и Objective C, чем я занимаюсь: -)

...