내 앱은 사용자에게 연락처 중 하나를 선택한 다음 연락처의 주소 중 하나를 선택하도록 요청합니다. 이 주소를 나타내는 데 사용할 "표시 이름"을 생성하려고합니다. 예를 들어 사용자가 John Smith의 주소 중 하나를 선택하면 표시 이름은 "John Smith"이고 UI는 그의 주소를 "John Smith 's 주소". 주소록에서이 이름을 추출하는 알고리즘은 다음과 같습니다.연락처 이름에 액세스하려고 할 때 내 앱이 중단되는 이유는 무엇입니까?
- 연락처가 업체 인 경우 업체명을 사용하십시오.
- 이름과 성이 있으면 "성 이름"을 사용하십시오.
- 이름이있는 경우 이름을 사용하십시오.
- 성이있는 경우 성을 사용하십시오.
- 문자열 "선택한 연락처"를 사용하십시오.
나는이 모든 논리를 구현했습니다. 문제는 두 개의 표시된 줄 중 하나에 충돌 (KERN_INVALID_ADDRESS
)이 표시되는 경우가 있음을 나타냅니다. 내 응용 프로그램은 ARC를 사용하며 Core Foundation에 대한 많은 경험이 없으므로 메모리 관리 또는 브리징을 잘못하고 있다고 가정합니다. 아무도 내가 뭘 잘못하고, 충돌을 해결하는 방법을 말할 수 있습니까?
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef) person
property:(ABPropertyID) property
identifier:(ABMultiValueIdentifier) identifier
{
[self dismissViewControllerAnimated:YES completion:NULL];
CFTypeRef address = ABRecordCopyValue(person, property);
NSArray *addressArray = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(address);
CFRelease(address);
NSDictionary *addressDict = [addressArray objectAtIndex:0];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressDictionary:addressDict completionHandler:^(NSArray *placemarks, NSError *error) {
if (error || !placemarks || [placemarks count] == 0) {
// tell the user that there was an error
} else {
NSString *name = contactName(person);
NSString *addressName = [NSString stringWithFormat:@"%@’s address", name];
// use `addressName` to refer to this address to the user
}
}];
return NO;
}
NSString* contactName(ABRecordRef person)
{
NSString *name;
// some crashes occur on this line:
CFNumberRef contactType = ABRecordCopyValue(person, kABPersonKindProperty);
if (contactType == kABPersonKindOrganization)
name = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonOrganizationProperty);
if (!name || [name length] == 0 || contactType == kABPersonKindPerson) {
// other crashes occur on this line:
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
if (firstName && [firstName length] > 0 && lastName && [lastName length] > 0)
name = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
else if (firstName && [firstName length] > 0)
name = firstName;
else if (lastName && [lastName length] > 0)
name = lastName;
if (!name || [name length] == 0)
name = @"Selected Contact";
}
CFRelease(contactType);
return name;
}