Пользовательский NSViewController освобождается после переключения приложения в фоновый режим и не может быть выпущен - PullRequest
0 голосов
/ 01 декабря 2018

Когда я переключаюсь на другое приложение, следующее мое взаимодействие с представлением иногда приводит к ошибке:

EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

Я переопределил метод deinit в CustomViewController для регистрации сообщения при его вызове,Следующие сообщения регистрируются в консоли при возникновении вышеуказанной ошибки.

CustomViewController is being deallocated
*** -[AppName.CustomViewController release]: message sent to deallocated instance 0x604000121b80

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

Мое приложение Cocoa до сих пор является относительно простым, все содержится в стандартном Main.storboard, созданном, когда я сначала создал проект, а затем обновил.Нет пользовательской раскадровки или кода инициализации контроллера.Все просто загружается и отображается, когда я запускаю приложение, прежде чем нажать свой собственный код.

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

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

Нет ничего особо выделяющегося в качестве потенциально проблемной области, которую я должен выделить.

Ближайшая эквивалентная проблема, которую мне удалось найти в Интернете, - эта .Но в этом сценарии они инициализируют свой контроллер вручную из раскадровки и не управляют ссылками на созданные экземпляры.Решение предполагает, что некоторая сборка мусора выполняется, когда приложение перемещается на передний план, что согласуется с тем, что я вижу, но не помогает мне решить проблему.

Еще один показывает аналогичную ошибку, но при сбое метода сохранения, а не при освобождении.Опять же, это включает в себя программную загрузку пера (в данном случае на iOS 5).

Ошибка появляется только тогда, когда я переключаю приложение на передний план, и это, кажется, попытка выпуститьпросмотр контроллера, который уже был выпущен.Когда я устанавливаю точку останова в методе deinit, я вижу, что он вызывается для экземпляра в порядке до сбоя вызова release, потому что тот же экземпляр уже освобожден.

Учитывая простую настройку, я уверенЯ делаю некоторые неправильные предположения здесь.Буду очень признателен за любую помощь.

Использование Swift 4 на macOS 10.13.6 с Xcode 10.1

1 Ответ

0 голосов
/ 02 декабря 2018

Следуя совету в этого ответа , я отследил проблему до пользовательского NSTableHeaderCell, который имел ссылку на CustomViewController.Ошибка освобождения всегда была связана с попыткой освободить пользовательский NSTableHeaderCell.

Я обнаружил две вещи, которые, по-видимому, связаны:

  1. Во-первых, ошибка в моем коде.Каждый раз, когда я обновлял данные, которые влияли на столбцы NSTableView, я заново создавал и назначал новый пользовательский экземпляр NSTableHeaderCell, даже если он уже был назначен, поэтому было много таких экземпляров, ожидающих сбора мусора.
  2. После устранения проблемы, описанной выше, первоначально проблема, казалось, была решена, но в конечном итоге снова возникла через более длительный период времени.Если посмотреть на время вызовов retain / release в шаблоне профилирования Instruments Zombies, то, возможно, возникла проблема с параллелизмом, когда было выполнено несколько вызовов Release, когда было освобождено несколько NSTableViewCell, что привело к снижению общего количества сохранений CustomViewController до нуля.и затем последующий запрос сохранения откуда-то на оставшейся ссылке зомби, который, как я полагаю, должен был прийти до последнего вызова релиза.

Я не уверен на 100%, была ли это проблема параллелизма или нет,но изменение ссылки на CustomViewController в пользовательском NSTableViewCell на слабую ссылку, по-видимому, решило проблему.

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

...