2016-10-21 1 views
2

Мой родительский объект создает дочерний объект для выполнения какого-либо действия async. Это связано с некоторым взаимодействием с пользователем, и это одна из причин, по которым я не использовал NSOperation. Только дочерний объект знает, когда он завершил свою задачу, то как он сообщает моему родительскому объекту, что я сделан, пожалуйста, освободите меня, чтобы избежать утечек памяти?В ARC как дочерний объект сообщает родительскому объекту, что я сделал, отпустите меня (чтобы избежать утечек памяти)

В настоящее время я придумал это, родительский объект имеет метод обратного вызова, называемый releaseChild, который равен child = nil; Когда дочерний объект заканчивает свою задачу, он вызывает родительский releaseChild, чтобы установить себя на нуль. Фактически, я завершаю вызов в dispatch_after, но идея такая же, дочерний объект вызывает ее родительский элемент, чтобы установить себя на нуль.

Мне было интересно, есть ли лучший способ?

----- обновление -----

Я знаю, что «нормальный» способ записать своего ребенка, чтобы создать UIViewController объект, нажмите на него, чтобы UINavigationController. Когда он будет закончен, пользователь может выскочить, ARC затем выпустит его. Таким образом, мне не нужно беспокоиться о утечке памяти (обычно). Но я думаю, что вопрос о выпуске дочернего объекта, когда он выполняется, и только он знает, когда это делается, имеет пограничное приложение, чем запись объекта UIViewController.

+0

Могу я узнать, какой тип детского класса? – CodeChanger

+0

Просто «нормальный» какао-объект с UI и сетевым материалом – Qiulang

+0

, поэтому для этого вам нужно переопределить метод 'dealloc()' в 'child' и вызвать этот метод с« дочерним »объектом из« parent »и сделать что-нибудь из вас хотите, чтобы там «выпустить». – CodeChanger

ответ

2

В вопросе:

только дочерний объект знает, когда он закончил свою задачу, то как это сказать, его родительский объект, который я сделал, пожалуйста, отпустите меня, чтобы избежать утечки памяти?

и в более позднем комментарии:

проблема является объект ребенка не может установить себя в ноль.

Возможно, вам нужен дочерний объект, который контролирует его собственную жизнь. Это легко сделать; объект остается в живых до тех пор, пока есть ссылка на него, хранящаяся в переменной, приписываемой как твердая собственность на хранящиеся в ней ссылки, - и этот атрибут является по умолчанию для объявлений переменных. Эта переменная может быть глобальной, локальной, экземпляра, это не имеет значения ... Итак, чтобы контролировать свою собственную судьбу, объект просто должен содержать ссылку на себя.

Следующий код, скопированный из Manual object lifetime with ARC (предыдущего ответа, который я написал несколько лет назад, я могу кроватку от себя ;-)), показывает один из способов сделать это:

@implementation MasterOfMyOwnDestiny 
{ 
    MasterOfMyOwnDestiny *alsoMe; 
} 

- (void) lifeIsGood 
{ 
    alsoMe = self; 
} 

- (void) woeIsMe 
{ 
    alsoMe = nil; 
} 

... 

@end 

В вашем случае может иметь дочерний набор alsoMe во время его инициализации, поэтому ребенок начинает управлять своим собственным временем жизни. Когда ребенок решает, что он закончил свою работу, он просто называет [self woeIsMe] своим финалом.

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

Если родитель должен иметь ссылку на ребенка по какой-либо причине, кроме как содержать ребенка в живых, то он может хранить эту ссылку в переменной, приписываемой как утверждающее слабую собственность на хранящиеся в ней ссылки, например. что-то вроде:

__weak MasterOfMyOwnDestiny *myChild = [MasterOfMyOwnDestiny new]; 

такая ссылка не будет держать объект, на который ссылается myChild живой, и будет автоматически установлен в nil когда умирает этот объект.

+0

Скажите мне, что я не знал. Благодаря! Я отметил ваш ответ как принятый, хотя ответ @ nasher729 работает. : D – Qiulang

1

Пара возможных решений

1) Использование метода протокола делегирования, чтобы позволить ребенку сказать родителю, что его сделали (я предполагаю, что тот, что вы делаете)

2) вы можете передать переменную в ребенка и который устанавливается ребенком после завершения его завершения, а родитель может периодически проверять его значение и очищать ребенка (а не большой поклонник, но вроде метода опроса), может выполняться с созданной фоновой задачей или может быть добавлен в очередь с низким приоритетом.

3) Используйте NSNotificationCenter, чтобы отправить уведомление родителям и сообщить ему о выполненных работах. Вы можете добавить userinfo для идентификации детей между собой.

4) Если вам не нужно делать что-либо конкретное после работы делается просто использовать dispatch_async и не содержать ссылку, она будет выполнять свою задачу и в конце концов утихнет

я потребовала бы более детально дать вам рекомендации по любому конкретному подходу. Если возможно, вставьте свой код :)

+0

+1 для 1) и 4), 3) работает, но не подходит, потому что уведомления являются неотправленным потоком информации (широковещательная передача), но родитель является выделенным объектом. 2) ... нет, ... действительно, нет. –

+0

@Amin Negm-Awad, проблема в том, что дочерний объект не может установить себя равным нулю. Это должно позволить кому-то другому (например, его родителям) сделать это. Поэтому я не вижу, как использование dispatch_async может сделать трюк. Помимо ответа, в некотором смысле это просто повторение того, что я сказал. Я ничего нового не вижу. Я определенно не буду использовать 2/3 (нет, нет трансляции) – Qiulang

+0

Решение 1) (делегирование) позволяет вам сообщить родителям, чтобы он мог установить свой ivar. Решение 4) верно: в вашем Q вы говорите, что проблема заключается в том, чтобы установить ссылку на ребенка на «nil». Поэтому больше нечего делать. В таком случае вам вообще не нужна детская ссылка. Просто удалите его. Блок удерживает ребенка в его закрытии. Конечно, это не сработает, если вам нужна ссылка по некоторым другим причинам (отмена?) –

1

Если дочерний объект выполняет асинхронную операцию, скорее всего, он имеет блок обратного вызова, который он вызывает, когда операция завершается с успехом или сбой. И, скорее всего, родительский объект создал дочерний элемент, сохранил ссылку, сказал ребенку запустить асинхронную операцию и дал ему блок обратного вызова. Так что обратный вызов будет идеальным местом для установки ссылки на nil.

+0

Привет, как ваше решение, так и работа @ CRD, но я буду отмечать его ответ как принятый ответ, потому что он рассказал мне то, что я раньше не знал. Извините: $ – Qiulang

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