Почему делегатам Objective C обычно дают, свойство присваиваются вместо, сохраняют?

<%@ page import="com.myproject.MyService" %>
<%
    def myService = grailsApplication.classLoader.loadClass('com.myproject.MyService').newInstance()
%>

И тогда вы можете вызвать ${myService.method()} в своем представлении gsp

Имейте в виду, что вызов транзакционных методов обслуживания из представлений снижает производительность. Лучше перенести все вызовы методов транзакционного обслуживания на контроллер (если вы можете)

176
задан Plumenator 8 September 2011 в 15:10
поделиться

3 ответа

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

A создает B A устанавливает себя как делегат B … A освобождается его владельцем

. Если бы B оставил A, A не был бы освобожден, поскольку B владеет A, таким образом, освобождение A никогда не будет вызвано, что приведет к утечке как A, так и B .

Вам не следует беспокоиться о том, что A уйдет, потому что он владеет B и, таким образом, избавляется от него в dealloc.

175
ответ дан 23 November 2019 в 20:23
поделиться

Поскольку объект, отправляющий сообщения делегата, не владеет делегатом.

Часто бывает наоборот, когда контроллер устанавливает себя в качестве делегата представления или окна: контроллер владеет представлением / окном, поэтому, если бы представление / окно принадлежало его делегату, оба объекта владели бы друг другом. Это, конечно, цикл сохранения, похожий на утечку с теми же последствиями (объекты, которые должны быть мертвыми, остаются живыми).

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

В любом случае объект с делегатом не должен сохранять своего делегата.

(Между прочим, есть как минимум одно исключение. Я не помню, что это было, и я не Не думаю, что для этого была веская причина. )


Добавление (добавлено 2012-05-19): В ARC вы должны использовать weak вместо assign . Слабые ссылки автоматически устанавливаются на nil , когда объект умирает, что исключает возможность того, что делегирующий объект в конечном итоге отправит сообщения мертвому делегату.

Если вы по какой-то причине избегаете ARC, по крайней мере, измените , назначьте свойства, которые указывают на объекты в unsafe_unrehibited , которые явно указывают, что это несохраняемая, но ненулевая ссылка на объект.

assign остается подходящей для значений, не являющихся объектами, как в ARC, так и в MRC.

44
ответ дан 23 November 2019 в 20:23
поделиться

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

17
ответ дан 23 November 2019 в 20:23
поделиться