2013-02-15 3 views
0

Я использую NSThread следующимNSThread Утечка памяти

NSThread * thread = [[NSThread alloc] initWithTarget:object selector:@selector(bg) object:nil]; 
[thread start]; 

Позже я хочу, чтобы остановить поток и освободить объект следующим образом:

[thread cancel]; 
[object release]; 

Это, кажется, работает нормально. Однако, когда я смотрю на инструмент утечек, я вижу, что некоторые загадочные утечки не приходят никуда от моего кода (пустой NSArray). Когда я смотрел историю malloc, я вижу, что NSArray выделяется в методе «willChangeValueForKey», который в конечном итоге называется моим [object dealloc]. Дело в том, что делегирование делегата равно нулю. Этот делегат наблюдается (поэтому willChangeValueForKey?). [Object dealloc] вызывается из [NSThread exit].

Я предполагаю, что это потому, что [thread cancel] не вращает нить сразу (в конце концов, это в другом потоке). И затем мы отпускаем объект на основной поток. Это оставляет значение keepCount в 1. Затем NSThread освободит объект, когда он действительно начнет вращаться. Похоже, что это вызывает утечку. Я попытался это быстрое изменение, чтобы подтвердить свое предположение:

[thread cancel]; 

[NSThread sleepForTimeInterval:1]; 
// This makes it wait until the thread releases [object] 

[object release]; 

Вопрос: почему это небезопасно позволить NSThread освободить свой объект? Это связано с тем, что код наблюдателя небезопасен в dealloc?

+0

Выполняется ли ваше 'willChange' /' didChange' в том же потоке, что 'addObserver:' и 'removeObserver:' вызывается? – iluvcapra

+0

Есть ли в вашей ветке собственный автореферат? –

+0

autoreleasepool: да. Что касается вопроса iluvcapra: я не уверен. Этот фрагмент кода довольно сложный, поэтому я не уверен на 100%. Могут ли иметь их на разных потоках вызвать утечку? – George

ответ

1

Ваш основной поток должен иметь возможность [object release] немедленно, вам не нужно ждать, пока вы отмените нить, или даже до тех пор, пока вы ее не запустили. initWithTarget: неявно сохраняет object и cancel неявно освобождает его.

Вам не нужно сохранять object на главной нити, чтобы поддерживать его в живом состоянии.

+0

Есть другие причины, по которым мне нужно держать объект «вокруг». Но я также не уверен, что это поможет. Кажется, что это происходит, когда релиз происходит из потока, который я запускал. – George

+0

Я немного отредактировал, чтобы позволить «объекту» не удержаться слишком много вещей, поэтому безопасно деалоковать его всякий раз. Я обнаружил, что проблема в том, что «объект» удерживался на другом объекте, который наблюдал сам. Основываясь на некоторых исследованиях, кажется, что наблюдение за собой не является хорошим примером. Так что это, вероятно, реальное решение здесь и будет тем, что я делаю в конце концов. Несмотря на то, что факторинг NSThread определен, все равно разумно. Спасибо за помощь. – George

+0

Я наблюдал «сам» раньше, и он работает, но наблюдение за границами потоков работает очень плохо. – iluvcapra

Смежные вопросы