Ответ прост: это унаследовано от UIViewController. Если вы просто добавляете представление viewController к вашему представлению, методы делегата не вызываются. ViewController имеет свой жизненный цикл. Пожалуйста, прочитайте здесь: s> https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller s>
Итак, извинения за то, что некоторые как-то не так. Конечно, вы можете добавить sub-viewController, показывающий только его вид. Но: я думаю, что это не должно быть вариантом использования. Это полноэкранный ViewController, соответствующий руководствам по дизайну от самого Apple. При этом вы должны представить его следующим образом:
func addPicker() {
var documentPickerController: UIDocumentPickerViewController!
documentPickerController = UIDocumentPickerViewController(documentTypes: [String(kUTTypePDF)], in: .import)
documentPickerController.delegate = self
documentPickerController.allowsMultipleSelection = false
present(documentPickerController, animated: true, completion: nil)
}
Имеются некоторые ошибки, из-за которых разработчик обнаружил, что представление отклоняется до вызова делегата. Насколько я видел, это поведение было введено с ios11 и произошло также, когда был представлен viewController. Я не могу сказать, исправлено ли это или нет, и связано ли это поведение с тем, чтобы показать его как подпредставление. (Я думаю, что это как-то исправлено, так как оно работает с представленным viewController)
В любом случае, вы должны просто представить его, как написано выше, и вы готовы к работе.
Я отправил связанный вопрос этому однажды это, Вы могли бы хотеть смотреть на: проблема с синхронизацией на Строковых объектах?
То, что я изучил, было: использование intern'ed Строки для синхронизации является плохой практикой.
Вполне. Проблема состоит в том, что key.intern () не действительно настолько уникален, потому что он возвращает строку из пула. String.intern () мог бы возвратить тот же объект, даже когда используется на различных объектах. Попытайтесь использовать key
самостоятельно или другой объект в целом.
Код почти наверняка пытается синхронизировать действия, которые влияют на тот же ключ. Таким образом, это звонит интерну (), чтобы гарантировать, что тот же ключ отображается на том же объекте и поэтому допустим как объект для синхронизации.
Проблема при столкновении с узким местом там (это не мертвая блокировка) состоит в том, что Вы переносите слишком много операций, входящих одновременно использование того же ключа.
Переосмысление, что потребности синхронизироваться.
Если необходимо синхронизироваться на Строке, не используйте Строковый экземпляр в качестве взаимного исключения (интернированный или не). Строка может использоваться для создания хорошего взаимоисключающего объекта, хотя: синхронизация на идентификаторе.
У Вас есть две проблемы. Тот использует Строку в качестве блокировки. Второй является мертвой блокировкой.
Если Вы использующий Строку в качестве блокировки, Вы потеряете контроль над тем, "кто" и "где" возьмет ту объектную блокировку.
Ваша проблема мертвой блокировки, которая может или не может вызванный, соединяет Строку. Однако истинная причина мертвой блокировки: "Ваш код может привести мертвую блокировку".. Если это может произойти, это произойдет.
Необходимо проследить стопки потоков для разрешения мертвых блокировок.
Существует недостаточно кода здесь для сообщения то, что идет не так, как надо. Это могло быть узкое место, как был упомянут, но по крайней мере один поток должен работать (с довольно тяжелым использованием ЦП), чтобы это произошел, или поток, который имеет блокировку, помещается для сна, не выпуская блокировку.
Мертвая блокировка является другой возможностью, но это потребовало бы, чтобы синхронизация на двух отдельных соединила несколько потоков, и Вы показали только один объект блокирования здесь.
Действительно невозможно определить без большей информации.
Как Мороженое говорит, key.intern () не обязательно даст Вам очень уникальный ключ для синхронизации на.
Необходимо быть осторожны относительно изменения кода, как бы то ни было. Необходимо понять стратегию блокировки в коде прежде, чем изменить его. При удалении интерна () вызов может дать Вам код, который, кажется, работает правильно, но содержит гонку данных, которая укусит Вас позже.
У Вас очень вероятно есть мертвая блокировка.
Если Вы хотите избежать мертвых блокировок, каждый поток должен всегда получать, привязывает тот же порядок. При использовании String.intern () для получения блокировок, Вы соединяете экземпляр, к которому любой код во всей JVM имеет доступ, и соединиться. Скорее всего, другие потоки в Вашем собственном коде заходят в тупик, но это не должно быть.
Я не уверен, что Вы имеете в виду в своем ответе "key.intern () уникальность гарантии". intern()
метод уменьшает уникальность путем возврата того же объекта для каждой строки, это эквивалентно.
String s1 = new String(new char[] { 'c', 'o', 'm', 'm', 'o', 'n' }).intern();
String s2 = new String("commo" + (s1.charAt(s1.length() - 1)).intern();
String s3 = "common";
if ((s1 == s2) && (s1 == s3))
System.out.println("There's only one object here.");
Код выше продемонстрирует даже при том, что Вы создали два уникальных экземпляра путем интернирования их, замену их единственным, каноническим экземпляром.
Существует опасность любое время, Вы используете объект, это видимо вне Вашего собственного кода как блокировка. Попытайтесь придерживаться членов парламента, не занимающих официального поста, объекты, что Вы не позволяете сбегать из своего собственного стека и т.д.
key.intern () гарантируют уникальность, потому что key.intern () возвращает строку из пула Строковых констант.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#intern () интерн
общедоступный Строковый интерн () Возвраты каноническое представление для строкового объекта. Пул строк, первоначально пустых, сохраняется конфиденциально классом Строка.
String.intern () является собственным методом - который мог бы быть причиной проблемы.