1

Учитывая, что self небезопасен в Objective-C, мы можем сказать, что нет оснований когда-либо вызвать методы или получить доступ к свойствам слабых объектов? то есть. Никогда не делайте этого:Есть ли веская причина для вызова методов на слабых объектах?

__weak typeof(self) weakSelf = self; 
dispatch_async(dispatch_get_main_queue(), ^{ 
    [weakSelf doStuff]; 
}); 

Конечно, технически это может быть хорошо, если есть еще одна сильная ссылка на самоопределение, которое гарантировано не оставаться в рамках, пока называется DoStuff, но это очень плохая причина.

Если нет веских причин, то не было бы хорошей идеей для компилятора просто отказаться от таких вызовов, по крайней мере, за вариантом компилятора?

+0

В ответ на ваш вопрос есть множество отличных причин использовать общий шаблон 'weakSelf', хотя по практическим соображениям мало смысла делать это точно так же, как в вашем примере. Это было сказано, мы, конечно, не хотели бы, чтобы компилятор отклонил этот шаблон. Мы можем легко построить сценарии, где мы хотим сделать именно это. Например, что, если это было в обработчике завершения запроса сети от контроллера представления, и завершило обновление объекта модели, а 'doStuff' затем обновлял пользовательский интерфейс? Вы можете сделать что-то очень похожее на то, что у вас здесь. – Rob

+0

Это была опечатка, я имел в виду небезопасную неохваченность. Вам, конечно, не нужно называть [weakSelf doStuff] для сетевого запроса. Вы всегда можете делать typeof (self) strongSelf = weakSelf; [strongSelf doStuff]; По-видимому, для слабых объектов объект по существу становится сильным во время doStuff, поэтому добавление strongSelf будет избыточным в этом случае. –

+0

Измененные прилагательные, описывающие причины от «сильных» и «слабых» до «хороших» и «бедных», чтобы не совпадало с терминологией управления памятью клана.Кроме того, считайте, что ссылка * действительно __weak * будет бессмысленной, потому что она будет выпущена сразу после назначения. – danh

ответ

2

От document вы ссылка:

Для __weak объектов, текущий pointee сохраняется, а затем выпустили в конце текущего полного выражения. Это должно выполняться атомарно в отношении присвоений и окончательной версии пункта.

Другими словами, weakSelf автоматически сохраняется на протяжении метода doStuff, так что это безопасно.

Как правило, вы должны преобразовать слабую ссылку в сильную ссылку, если вы вызываете более одного метода/свойства.

+0

А, ок. Мой вопрос исходил из ответов в этом вопросе: http://stackoverflow.com/questions/32468758/objective-c-arc-does-a-method-retain-self. Я думаю, что тогда эти ответы неверны. –

-1

мы можем в целом сказать, что нет серьезных оснований когда-либо вызывать методы или свойства доступа на слабых объектов

Нет, это не имеет никакого смысла. Вы постоянно вызываете методы на слабых объектах! Например, в Cocoa большинство объектов delegate: weak - как и должно быть, так как было бы неправильно, если бы объект оставил свой делегат. Однако вызов метода делегата - это суть шаблона делегата; в противном случае, что является делегатом для?

Пример: вот как UIApplication delegate объявлен:

@property(nullable, nonatomic, assign) id<UIApplicationDelegate> delegate; 

То есть слабая ссылка, не ARC (то есть какие assign средства). Но вы никогда не скажете, что никакие сообщения не могут быть отправлены делегату приложения, не так ли?

+0

Никогда не вызывать методы на слабых объектах не означает, что вы никогда не будете их использовать. Это просто означает, что вы должны сделать их сильными первыми. Но, как указал Даррен, компилятор уже делает это за вас. –

+0

Но я не верю в это. Компилятор не делает слабый «делегат» сильным. Напротив, отправка сообщения в «делегат», который больше не существует, представляет собой классическую ситуацию с «зависанием». Это небезопасно. Ничто не делает его сильным; если бы это произошло, мы бы не рухнули. Но это не глупая или плохая ситуация; вам просто нужно предпринять шаги, чтобы сохранить его в безопасности. Убедившись, что делегат переживает объект со слабой ссылкой на него, это часть вашей работы, вот и все. Но сказать, что это как-то не слабая ссылка - это просто глупость. Конечно, он слабый. – matt

+0

Что вы не верите в ту часть документации, которая гласит: «Для объектов __weak текущий указатель сохраняется, а затем освобождается в конце текущего полного выражения». Если он сохранен, то он не будет выпущен (как если бы была сильная переменная, ссылающаяся на него). Если делегат будет освобожден, слабая ссылка станет нулевой. Использование объекта nil не приведет к сбою, если вы не сделаете что-то конкретное с ним, например, добавьте его в массив или напрямую получите доступ к ivar. Это совершенно отдельная дискуссия, а не вопрос. –