Проблема памяти листа и нити - PullRequest
0 голосов
/ 05 апреля 2010

Недавно я запустил проект, который может экспортировать некоторые предварительно рассчитанные файлы Grafix / Audio в файлы для последующей обработки.

Все, что я делал, это вставлял новое окно (с индикатором прогресса и кнопкой отмены) в мой основной xib и открывал его, используя следующий код:

[NSApp beginSheet: REC_Sheet modalForWindow: MOTHER_WINDOW modalDelegate: self didEndSelector: nil contextInfo: nil];

NSModalSession session=[NSApp beginModalSessionForWindow:REC_Sheet];
RECISNOTDONE=YES;
while (RECISNOTDONE) {
    if ([NSApp runModalSession:session]!=NSRunContinuesResponse)
        break;
    usleep(100);
}

[NSApp endModalSession:session];

Фоновый поток (pthread) был запущен ранее, чтобы фактически выполнить работу и сохранить весь файл targas / wave. Это прекрасно работало, но через некоторое время выяснилось, что основной поток больше не отвечает, и мой объем памяти увеличился и его невозможно остановить. Я попытался отладить его с помощью Instruments и увидел, как много CFHash и т. Д. Растет до бесконечности.

Случайно я щелкнул ниже листа, и временно это помогло, основной поток (AppKit?) Выпускал свои вещи, но только на некоторое время.

Я не могу объяснить это мне, во-первых, я думал, что это был доступ моего потока к панели прогресса для обновления прогресса (с интервалом в 0,5 секунды), поэтому я вырезал его. Но даже если я ничего не обновляю и ничего не делал с Progressbar, мое приложение пожирает всю память, потому что не выпускает его «Main-Event» или что-то еще.

Есть ли возможность «истощить» этот основной поток памяти (вызов Runloop / NSApp?). И почему, черт возьми, Основной поток больше не отвечает (после этой простой задачи) ???

У меня больше нет облаков, пожалуйста, помогите!

Заранее спасибо!

P.S. Как вы, ребята, реализуете «многопоточное длинное задание» и обновляете свой графический интерфейс ???

1 Ответ

1 голос
/ 06 апреля 2010
while (RECISNOTDONE) {
    if ([NSApp runModalSession:session]!=NSRunContinuesResponse)
        break;
    usleep(100);
}

Есть ли причина, по которой вы это делаете?Лист заблокирует родительское окно без необходимости делать что-либо подобное.Вы можете запретить выход в делегате приложения.

Если вам действительно нужен вышеуказанный код для чего-то, попробуйте создать пул автоматического выпуска перед отправкой сообщения runModalSession:, а затем опустошить его (но перед сравнением с NSRunContinuesResponse и перерыв).

...