2014-12-12 3 views
0

여기 거래가 있습니다 :iOS 주소록 신속한 BadAccess

iPhone의 내부 주소록에 액세스하는 앱을 구축 중입니다. 모든 것이 잘 작동했다 (여전히 시뮬레이터에서 잘 작동),하지만 지금은 장치에 나는 ThreadBreak을 얻고 lldb이 줄의 콘솔에 오류 메시지와 함께 열립니다 다시

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

이있다 여전히 시뮬레이터 마음에 당신과 잘 작동하는 데 사용됩니다.

내가 위의 GCD를 사용하여 백그라운드에서 메모리로 주소록을로드하고 있기 때문에 일어나고 일부 멀티 스레드 작업이 :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { 

내 주소록이 제대로로드. 내 테스트 장치 (아이폰 6)에서 앱을 삭제하고, 프로젝트를 정리했다. ABAddressBook 데이터 유형을 좋아하지 않는 일부 Obj-C 브릿지 파일과 북쪽으로 행운을 빌어 요. 아무 일도 없었어요 .

나는 그것이 모든 시뮬레이터에서 작동하고 전화로 작동하지 않는 이유를 알 수 없습니다. 그러나 앱이 전화를받지 못했습니다. 이 최초 연락처는 삭제 한 후 열립니다 (권한 부여 검사가 호출 불구하고 권한 부여됩니다) : 여기 내가 아무것도의 많은 부분을 반환 아니에요 이후 모두 표시하는 경우에도 무엇 손실에있어

case .Authorized: 
     return self.createAddressBook() 

을하지만, 망설이다. 스레드 오류의 WN (참고 : 때때로 다른 스레드에서 발생 ...) 중단 점에

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) 

내 변수가 모두 포함 된 my app 다른 곳에서 사용합니다.

너무 장황한 것에 대해 사과드립니다. 그러나이 주제가 무엇이며 관련이없는 것은 아닙니다. 사전에 도움을 주셔서 감사합니다!

업데이트 : 멀티 스레딩/디스 패칭이 꺼져 있고 작동하지 않았습니다. 그래서 그것은 그 tempPerson.firstname 비트와 관련이 있어야합니다.

업데이트 2 : 루프가 두 번 돌아가고 실패하기 전에 두 개의 연락처가 표시됩니다. 나는 비록에 대한 다음과 같은 검사를해야합니까 ..이 연락처 중 일부에 대한 아주 nil이 아닌 전무 값을 타격 한 후 충돌 생각하며 통과된다

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 ?? "" 

을 문제는 어떤 사람들은 다양한 이유로 정말 더러운 addressbooks을 가지고 있으며, 심지어 일부는 혼합해야한다는 것입니다 firstname 속성없이 "LastName, FirstName SPACE Birthday"가 포함 된 lastname 속성을 갖는 것과 같은 속성.

이유가 무엇이든 먼저 NSObject BEFORE를 String으로 typecasting하는 것이 잘 작동하는 것 같습니다.