2015-12-17 1 views
1

Как ни странно, нет никакой команды для одновременного удаления всех представлений вида. Тем не менее, подвиды массив вида не непреложный копия внутреннего списка подвидов, поэтому он является законным к циклу через него и удалить каждый подвид поштучно:Я был смущен неизменной копией и изменяемой копией в Objective-C

for v in myView.subviews as [UIView] { 
    v.removeFromSuperview() 
} 

Это содержание в Программирования IOS 8, если копия является неизменной копией, почему она может измениться?

ответ

5

Я не думаю, что вы действительно спрашиваете об неизменяемых массивах здесь, так как вы не вызываете никаких методов в самом массиве, так что это изменчивость не может быть проблемой. Неизменяемым атрибутом массива subviews является то, как представление решило представить список вам. Это не имеет никакого отношения к тому, как подчиненные представления взаимодействуют с родительскими представлениями.

Вы, кажется, смущены тем, почему subview может удалить себя из родительского представления, и вы не можете; это просто потому, что subview является UIView -subclass, а родительский вид - UIView -subclass, и поэтому subview имеет доступ ко всем внутренним переменным родителя и может делать все, что ему нравится родительскому. Ты не можешь. Это преднамеренно, поскольку вы не знаете тонкостей иерархии представлений (и не хотите), где, как это делает UIView.

Еще один интересный аспект кода, который вы опубликовали, заключается в том, что часто получение элемента в массиве для удаления из массива при его перечислении вызовет исключение. В этом конкретном случае, однако, массив subviews, который вы получаете из представления, представляет собой copy оригинала (неизменяемая копия), и поэтому получение субвью для удаления из родительского представления не повлияет на этот массив, и перечисление не будет мешать. Спасибо Кристоферу Кевину Хауэлл за это, поскольку я пропустил его полностью, в первый раз.

+0

Я помечаю его неправильно @ ~ @ – lolita

+0

Этот код я читаю из книги программирования IOS 8, я не понимаю, он сказал, что подвид является неизменной копией внутреннего списка, но почему он может удалить элемент из него, когда итератор. – lolita

+0

Я предпочитаю стандартную для в петлю в Swift: для подвида в подобозрениях { subview.removeFromSuperview() } –

1

Массив subviews неизменен, поэтому вы не можете его изменить. Например, вы не можете самостоятельно удалить элемент массива или перезаписать его совершенно новым массивом.

Тем не менее, нет ничего, что помешало бы внутренней реализации класса изменить его, переписав его внутренне.

В этом случае возвращаемый массив subviews является копией фактического массива subviews.

+0

+1 Хммм, я пропустил атрибут 'copy' в свойстве' subviews'; рендеринг половины моего ответа недействителен: - |. Я попытаюсь уменьшить урон. – trojanfoe

+0

Насколько я знаю, я думаю, что атрибут 'copy' определяет только то, как объект установлен (следовательно, почему я отредактировал мой ответ!). Я думаю, что Apple целенаправленно переопределяет метод «subviews» getter, чтобы вернуть копию, так как многие люди, вероятно, сталкиваются с сбоями, пытаясь удалить subviews. В любом случае, это хороший вопрос от пользователя @ user2687943! –

+0

Я понимаю, что атрибут 'copy' влияет как на getter, так и на setter. – trojanfoe