Передача массивов / объектов между ViewControllers в Swift

Исходя из этого вопроса: есть ли причина, что распределение массива Swift является непоследовательным (ни ссылка, ни глубокая копия)? –

Я играл с проходящими объектами в Свифте и замечал некоторые странные результаты.

Чтобы прояснить тип поведения, к которому я привык (до Swift), относится к Objective C.

Чтобы привести пример в одной из моих приложений (написанной в Obj C), у меня есть концепция «списка уведомлений». – действительно просто массив пользовательских объектов.

В этом приложении я часто передаю свой глобальный массив «уведомлений» на различные viewControllers, которые предоставляют пользовательский интерфейс для обновления списка.

Когда я передаю глобальный массив дочернему элементу viewController, я назначаю его локальной переменной массива в объекте получателя. Затем, просто обновляя / изменяя локальный массив, эти изменения отражаются в глобальном массиве на rootViewController . Я понимаю, что это поведение подразумевается в Objective C как объекты, передаваемые по ссылке, но это действительно удобно, и я пытаюсь воспроизвести это поведение в Swift.

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

Сначала я попытался передать массив строк Swift (не NSMutableArray) из rootViewController в дочерний viewController (как описано выше).

Вот поведение при передаче в массиве Strings дочернего viewController:

Я проходил мимо:

[Билл, Боб, Джек], а затем назначить этот переданный массив локальному массиву для локальной модификации ,

Затем я добавляю строку «Фрэнк» к локальному массиву

Результаты:

Локальный массив = [Билл, Боб, Джек, Фрэнк]

Глобальный массив = [Билл, Боб, Джек]

Никакие изменения в локальном массиве не возвращаются в глобальный массив. – То же самое происходит для изменения элемента (без изменения длины массива).

Я также попробовал описанный выше эксперимент с примером более реального мира – передав массив моих пользовательских объектов «уведомления» дочернему элементу viewController. ИСТОЧНИЙ результат возникает, когда ни одно из изменений в локально назначенный массив настраиваемых объектов не отражается в исходном глобальном массиве, который был передан.

Это поведение нежелательно для меня, я полагаю, что наилучшей практикой здесь является использование делегатских протоколов для передачи измененного массива (или любого другого объекта) обратно в родительский объект, а затем для ручного обновления глобального массива? – если это так, это создает дополнительную нагрузку на поведение Objective C.

Наконец, я попробовал ключевое слово inout , которое эффективно позволяет вам напрямую изменять параметр функции var, переданный объекту назначения.

Изменения отражаются обратно на глобальный массив (или объект). Однако проблема заключается в том, что если входной параметр назначается локальной переменной (для редактирования вне области действия функции init), изменения в локальной переменной все еще не отражены в глобальной области ,

Я надеюсь, что это имеет смысл. Это действительно удушает мою производительность с помощью Swift.

Я что-то упустил или это шизофреническое поведение ожидается?

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

2 Solutions collect form web for “Передача массивов / объектов между ViewControllers в Swift”

Связанный вопрос дает ответ – это для производительности.

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

По моему мнению, дизайн, основанный на побочных эффектах, является ошибочным.

Если функции должны модифицировать «глобальные», то они должны либо возвращать новое значение, либо если это невозможно, вы должны обернуть свой массив внутри объекта и предоставить соответствующие функции для управления значениями данных.

Swift размывает линии между внутренним и объектом несколько с массивами, что делает его немного запутанным – в Objective-C NSMutableArray является объектом, поэтому он всегда передается по ссылке.

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

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

Почему бы вам не создать класс Model, содержащий массив как var. Добавьте методы в класс Model для управления массивом и сохраните новый экземпляр в свойстве. Создайте один экземпляр класса Model при запуске и передайте его контроллерам вида. Все они получают доступ к массиву через модель или через методы класса Model. Поведение Swift (где он копирует массив при изменении размера) будет скрыто от всех контроллеров представления.

  • UIButton никогда не запускает код в Action
  • Swift - сохранить флажки, выбранные в TableView
  • UIButton перестает показывать действия UIControl в построителе интерфейса после добавления к нему расширения
  • Выровнять SpriteNode с поверхностью при столкновении SpriteKit Swift3
  • SWIFT 3 - вытащите html-теги из строки, взятой из веб-сайта JSON
  • Экран камеры показывает только чистое черное изображение
  • Ссылка Branch.io для iOS 9+
  • Что такое «развернутое значение» в Swift?
  • Управление обновлением UITableViewController равно нулю
  • Сплошные столкновения SpriteKit SKPhysicsBody
  • UITableView при изменении ограничения, влияющего на высоту ячейки после удаления, заканчивается сломанными ограничениями
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.