2014-12-12 4 views
0

Так вот сделка:iOS AddressBook Swift BadAccess

Я создаю приложение, которое обращается к внутренней адресной книге на iPhone. Все работает нормально (и работает отлично на тренажере все еще), но теперь на устройстве я получаю ThreadBreak и lldb открывает без сообщения об ошибке в консоли на этой линии:

tempPerson.firstname = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as String? ?? "" 

Опять же, это все еще работая над симулятором, и вы очень хорошо работали.

Существует несколько многопоточного действия происходит потому, что я загрузку в память адресной книги в фоновом режиме, используя НОД выше:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { 

Моего Addressbook был загружен правильно. Я удалил приложение с моего тестового устройства (iPhone 6), очистил проект (считая, что это может быть плохая связь между некоторым файлом моста Obj-C, которому не понравился тип данных ABAddressBook, и даже прыгал на одной ноге, удерживая телефон на север к счастью. Ничего не работало

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

case .Authorized: 
     return self.createAddressBook() 

Я теряюсь в даже то, чтобы показать вам все, так как он не возвращался много всего, но здесь это прорыв шп от ошибки резьбы (Примечание: Иногда это происходит в разных потоках ...)

Thread 4 
Queue: com.apple.root.background.-qos (concurrent) 

0 swift_getObjectType 
1 swift_dynamicCast 
2 SomeApp.ViewController.(createAddressBook(SomeApp.ViewController) ->() -> Swift.Bool).(closure #1) 
3_Dispatch_call_block_and_release 
4_dispatch_client_callout 
5_dispatch_root_queue_drain 
6_dispatch_worker_thread3 
7_pthread_wqthread 

Enqueued from com.apple.main-thread (Thread 1) 

0_dispatch_async_f_slow 
*>> 1_SomeApp.ViewController.createAddressBook(SomeApp.ViewController)() -> Swift.Bool [inlined] 
2_SomeApp.ViewController.determineStatus(SomeApp.ViewController)() -> Swift.Bool 
3_SomeApp.ViewController.loadContacts(SomeApp.ViewController() ->() 
4_SomeApp.ViewController.viewDidLoad(SomeApp.ViewController() ->() 

... etc Viewloading stuff 

На контрольной точке, две переменные, приведенные в отладчике являются

addressbookref

adbk = (AnyObject?) (instance_type = Builtin.RawPointer = 0x...  EvaluatingTo: Some 

и ViewController под названием «Self»

self(SomeApp.ViewController) 

содержащий все переменные мое приложение использует в другом месте.

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

Обновление: Я отключил многопоточность/диспетчеризацию, и это не сработало. Так что это должно быть связано с тем, что tempPerson.firstname бит.

Обновление 2: он дважды обходит цикл и получает два контакта перед сбоем. Я думаю, что это бьет в ноль значение, которое не совсем ноль для некоторых контактов, а затем сбой .. У меня есть следующий чек на него, хотя и проходит через:

if ABRecordCopyValue(person, kABPersonFirstNameProperty).takeRetainedValue() as AnyObject? != nil{ 

&

if ABRecordCopyValue(person, kABPersonLastNameProperty).takeRetainedValue() as AnyObject? != nil{ 

соответственно.

Обновление 3: Хорошо. Итак, теперь, когда появляется пустое поле для имени или фамилии, он сбой (на симуляторе теперь тоже). Который действительно сосет, потому что я думал, что поставил хороший чек, чтобы убедиться, что я не получаю доступ к нулевым свойствам. Еще более раздражает то, что я не изменил этот код, и он работал нормально, пока я не удалил некоторые производные данные и не изменил тестовый файл, чтобы избежать ошибки компоновщика. Что-нибудь, что может произойти в процессе сборки, который удаляет мой код?

+2

«Я загружаю адресную книгу в память в фоновом режиме». Можно спросить, почему вы это делаете? Это может быть причиной проблемы и совершенно ненужно. Нет необходимости в многопоточности, форме или форме при работе с адресной книгой. См. Мой пример кода: https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch18p713addressBook/ch31p973addressBook/ViewController.swift Обратите внимание, что я никогда ничего не делаю с потоками, кроме как вернуться к _main_ поток в обработчике завершения авторизации. – matt

ответ

0

В принципе, вы должны действительно проверить ваш тип проливает при доступе к адресной книге, см:

tempPerson.lastname = ABRecordCopyValue(person, kABPersonLastNameProperty).takeRetainedValue() as NSObject as? String ?? "" 

Проблема заключается в том, что некоторые люди имеют очень грязные адресные книги по разным причинам, и даже некоторые перепутаны такие свойства, как свойство last name, которое содержит «LastName, FirstName SPACE Birthday» без свойства firstname.

По какой-то причине приведение типов сначала как NSObject ПРЕЖДЕ, как к строке, кажется, работает хорошо.

Смежные вопросы