0

У меня есть метод объекта, который создает объекты, которые затем передаются к способу другого объекта в другом потоке, как это:объекты Autoreleasing, созданные в потоке и передается к другому в Objective-C

MyClass* myClass = [[MyClass alloc] init]; 
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO]; 

в методе, я немедленно сохраняю объект, предполагая, что он будет каким-то образом выпущен создателем. Мой вопрос: как мне заставить MyClass правильно освободить этот объект? Правильно ли это?

Моим решением было освободить объект вручную в методе. Я все равно вижу, что анализатор утечек по-прежнему распознает это как утечку, и, похоже, это не то, что рекомендует Apple, так как владелец несет ответственность за выпуск объекта.

Можете ли вы объяснить мне правильный способ справиться с этой ситуацией? Благодаря!

+0

Ой, извините, я забыл важный элемент: поток, который выполняет инструкцию, о которой я сообщил, не является потоком какао. Я создал его с помощью потоков POSIX. –

+0

Нет никакой разницы между потоками какао и потоками POSIX. Но убедитесь, что вы создали пул автозапуска в начале потока. – Yuji

+0

Я прочитал также необходимо создать хотя бы один NSThread, чтобы иметь возможность использовать NSAutoreleasePools. –

ответ

9

Я не совсем понимаю, что вы пытаетесь достичь, но в целом:

Вы не должны беспокоиться о том, кто и когда релизы/освобождает объект. Вместо этого просто убедитесь, что сохраните его, когда вы (ваш единственный объект или ваш метод) начните с него и отпустите его, когда вы прекратите его (или авторизуйте его, и в этом случае он будет выпущен в потоке на который вы назвали autorelease).

Это как раз то, как работает performSelectorOnMainThread:withObject:waitUntilDone:. От documentation:

Этот метод сохраняет ресивер и параметр arg до тех пор, пока селектор не будет выполнен.

Он сохраняет их, пока они нуждаются в них для выполнения его работы.

Короче говоря, mehod, что создает объекты и отправляет их на другой поток должен быть:

MyClass* myClass = [[MyClass alloc] init]; // retained, will need it for performSelector 
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO]; 
[myClass release]; // no longer needing it. 

или

MyClass* myClass = [[[MyClass alloc] init] autorelease]; // will be released automatically, but guaranteed to be retained until this method returns 
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO]; 

, как вы есть сейчас является утечку памяти.

Метод получающий:

  • , если он использует объект только внутренне, не должен сохранить его, так как performSelector делает «только после его проведения» (возврат метода).
  • , если это необходимо позже, оно должно быть присвоено собственности, которая его сохраняет.
+1

Я думаю, что это именно то, что мне нужно: performSelectorOnMainThread сохраняет его и выпускает, когда это делается. Это то, что мне нужно, потому что теперь я могу освободить после выполнения функцииSelectorOnMainThread, как вы сказали, будучи уверенным, что он не будет освобожден при использовании. Надеюсь, я правильно понял! Благодаря! –

+0

В документации больше не содержится информации об управлении памятью '-performSelectorOnMainThread: withObject: waitUntilDone:'. Спасибо за этот ответ. – Greg

0

Ваш вопрос очень трудно понять, потому что вы говорите об этом объекте, этот объект, другой объект и использовать бессмысленные имена, как MyCLASS, anotherClass и методом. Остается неясным, какой объект вы намерены выпустить, а какой - утечка.

Во всяком случае, многопоточность не добавляет особых сложностей в подсчет ссылок. Конечно, ваши два объекта myClass и otherClass не являются недолговечными объектами. Поэтому, если вы используете autorelease, убедитесь, что счетчик ссылок не переходит в 0, если все автореализаторы выполнены.

Это совершенно нормально, чтобы выпустить либо MyCLASS или anotherClass или как в методе.

У вас нет большого кода. Но то, что вы показываете, в порядке.

+0

Извините, если я не понял. Я могу назвать классы и методы каким-то другим способом, но концепция заключается в том, что я создаю объект в методе и передаю его с помощью функции performSelectorOnMainThread. Вопрос в том, как правильно отпустить этот объект? Если я не ошибаюсь в другом ответе, это то, чего мне не хватало: performSelectorOnMainThread сохраняет его и отпускает, когда это делается. Благодаря! –