gpt4 book ai didi

iphone - ABRecordCopyValue 和 ABPropertyID 崩溃

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:51:26 25 4
gpt4 key购买 nike

我正在尝试从 iPhone 通讯录中检索数据,但遇到了一些问题。

首先,我有一个包含所有联系人的数组 (self.allContacts):


ABAddressBookRef abRef = ABAddressBookCreate();
self.allContacts = (NSMutableArray*)ABAddressBookCopyArrayOfAllPeople(abRef);

我还有一个名为 self.allKeys 的所有属性数组(每个属性都是字符串)。

当我尝试使用 self.allKeys 中的属性获取属性时发生崩溃:


NSString *currentRecord = [[NSString alloc] init];
ABRecordRef currentRecordRef;
ABPropertyID currentFieldProperty;

currentRecordRef = (ABRecordRef)[self.allContacts objectAtIndex:i];
currentFieldProperty = (ABPropertyID)[self.allKeys objectAtIndex:j];

currentRecord = (NSString*)ABRecordCopyValue(currentRecordRef, currentFieldProperty);

问题是将 currentFieldProperty 传递给 ABRecordCopyValue 会导致崩溃。


  • self.allContacts 是所有联系人的数组
  • self.allKeys 是所有属性的数组(每个属性都是字符串)

当尝试从 ABRecordCopyValue 检索单个属性时,它会导致 EXC_BAD_ACCESS 崩溃。

谢谢!

最佳答案

设置NSZombieEnabled , MallocStackLogging , 和 guard malloc在调试器中。然后,当您的应用程序崩溃时,在 gdb 控制台中输入:

(gdb) info malloc-history 0x543216

将 0x543216 替换为导致崩溃的对象的地址,您将获得更有用的堆栈跟踪,它应该可以帮助您查明代码中导致问题的确切行。


- 更多想法 -

如果self.allKeys确实是

"an array of all properties (each property as string)"

那么您可能应该获取数组对象(属性)的 intValue,因为 ABPropertyID 只是一个 typedef int32_t。像这样的东西:

currentFieldProperty = (ABPropertyID)[[self.allKeys objectAtIndex:j] intValue];
ABRecordCopyValue(currentRecordRef, currentFieldProperty)

但我们需要查看 self.allKeys 中的值或它是如何填充的才能确定。

来自 ABRecordRef ReferenceCFTypeRef Reference

ABRecordCopyValue - Returns the value of a record property.

    CFTypeRef ABRecordCopyValue (
ABRecordRef record,
ABPropertyID property
);

Parameters
record - The record containing the property in question.
property - The property of record whose value is being returned.

Return Value
The value of property in record.

和:

ABPropertyID - Integer that identifies a record property.
typedef int32_t ABPropertyID;


- 以及更多故障排除思路 -

如果不是以上情况,那么你的crash可能是在(NSString*)ABRecordCopyValue(currentRecordRef, currentFieldProperty) 所以这里有一个小的辅助函数可以解决这个问题:

- (NSString*)stringValueForCFType:(CFTypeRef)cfValue {
NSString *stringValue = nil;
if (!cfValue) return nil;
CFTypeID cfType = CFGetTypeID(cfValue);
if (cfType == CFStringGetTypeID()) {
stringValue = [[(id)CFMakeCollectable(cfValue) retain] autorelease];
} else if (cfType == CFURLGetTypeID()) {
stringValue = [(NSURL*)cfValue absoluteString];
} else if (cfType == CFNumberGetTypeID()) {
stringValue = [(NSNumber*)cfValue stringValue];
} else if (cfType == CFNullGetTypeID()) {
stringValue = [NSString string];
} else if (cfType == AXUIElementGetTypeID()) {
stringValue = [[GTMAXUIElement elementWithElement:cfValue] description];
} else if (cfType == AXValueGetTypeID()) {
stringValue = [self stringValueForAXValue:cfValue];
} else if (cfType == CFArrayGetTypeID()) {
stringValue = [self stringValueForCFArray:cfValue];
} else if (cfType == CFBooleanGetTypeID()) {
stringValue = CFBooleanGetValue(cfValue) ? @"YES" : @"NO";
} else {
CFStringRef description = CFCopyDescription(cfValue);
stringValue = [(id)CFMakeCollectable(description) autorelease];
}
return stringValue;
}

然后执行 currentRecord = [self stringValueForCFType:ABRecordCopyValue(currentRecordRef, currentFieldProperty)]; 并检查以确保 self.allKeys 在索引 j 处有一个对象self.allContacts 在索引 i 处有一个对象:

NSString *currentRecord = [[NSString alloc] init];
ABRecordRef currentRecordRef;
ABPropertyID currentFieldProperty;

if (self.allContacts.count > i) {
currentRecordRef = (ABRecordRef)[self.allContacts objectAtIndex:i];
if (self.allKeys.count > j) {
currentFieldProperty = (ABPropertyID)[self.allKeys objectAtIndex:j];
currentRecord = [self stringValueForCFType:ABRecordCopyValue(currentRecordRef, currentFieldProperty)];
} else {
NSLog(@"self.allKeys has no value at index (%d): %@", j, [allKeys description]);
}
} else {
NSLog(@"self.allContacts has no value at index (%d): %@", i, [allContacts description]);
}

编辑(关于评论):

要将属性名称的字符串转换为其 int 值,您需要创建以下内容(这可能不是他们需要的正确顺序,所以 NSLog 他们先看看是什么他们需要的顺序):

NSString * const ABPropertyID_toString[] = {
@"kABPersonFirstNameProperty",
@"kABPersonLastNameProperty",
@"kABPersonMiddleNameProperty",
@"kABPersonPrefixProperty",
@"kABPersonSuffixProperty",
@"kABPersonNicknameProperty",
@"kABPersonFirstNamePhoneticProperty",
@"kABPersonLastNamePhoneticProperty",
@"kABPersonMiddleNamePhoneticProperty",
@"kABPersonOrganizationProperty",
@"kABPersonJobTitleProperty",
@"kABPersonDepartmentProperty",
@"kABPersonEmailProperty",
@"kABPersonBirthdayProperty",
@"kABPersonNoteProperty",
@"kABPersonCreationDateProperty",
@"kABPersonModificationDateProperty",
@"kABPersonAddressProperty",
// ... etc
};

- (NSString *)ABPropertyIDToString:(ABPropertyID)propertyVal {
return ABPropertyID_toString[propertyVal];
}

- (ABPropertyID)stringToABPropertyID:(NSString *)propertyString {
int retVal;
for(int i=0; i < sizeof(ABPropertyID_toString) - 1; ++i) {
if([(NSString *)ABPropertyID_toString[i] isEqual:propertyString]) {
retVal = i;
break;
}
}
return retVal;
}

然后传递 stringToABPropertyID: 数组 [self.allKeys objectAtIndex:j] 的值,您将返回一个 ABPropertyID:

currentFieldProperty = [self stringToABPropertyID:[self.allKeys objectAtIndex:j]];

关于iphone - ABRecordCopyValue 和 ABPropertyID 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7746111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com