ABRecordCopyValue 和 ABPropertyID 崩溃
我正在尝试从 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
崩溃。
谢谢!
I'm trying to retrieve data from the iPhone address book and I have some problems.
First of all, I have an array of all contacts (self.allContacts
):
ABAddressBookRef abRef = ABAddressBookCreate();
self.allContacts = (NSMutableArray*)ABAddressBookCopyArrayOfAllPeople(abRef);
I also have an array of all properties (each property as string) called self.allKeys
.
The crash occurs when I try to get the properties using a property from 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);
The problem is that passing currentFieldProperty
to ABRecordCopyValue
causes a crash.
self.allContacts
is an array of all contactsself.allKeys
is an array of all properties (each property as string)
When trying to retrieve a single property from ABRecordCopyValue
it causes an EXC_BAD_ACCESS
crash.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
设置 NSZombieEnabled,MallocStackLogging 和 在调试器中保护 malloc。然后,当您的应用程序崩溃时,在 gdb 控制台中输入以下内容:
将 0x543216 替换为导致崩溃的对象的地址,您将获得更有用的堆栈跟踪,它应该可以帮助您查明代码中发生崩溃的确切行。导致了问题。
- 更多想法 -
如果
self.allKeys
确实是那么您可能应该获得数组对象(属性)的
intValue
,因为ABPropertyID
只是一个typedef int32_t
。类似于:但是我们需要查看 self.allKeys 中的值或如何填充它才能确定。
来自 ABRecordRef 参考 和 CFTypeRef 参考
并且:
- 以及更多故障排除思路 -
如果不是上述情况,那么当您将
CFTypeRef
转换为NSString * 时可能会导致崩溃
in(NSString*)ABRecordCopyValue(currentRecordRef, currentFieldProperty)
所以这里有一个小辅助函数可以解决这个问题:
currentRecord = [self stringValueForCFType:ABRecordCopyValue(currentRecordRef, currentFieldProperty)];
并检查以确保self.allKeys
在索引j
处有一个对象,并且self.allContacts
在索引i
处有一个对象:编辑(关于注释):
要将属性名称的字符串转换为其 int 值,您可以需要创建以下内容(这可能不是它们需要的正确顺序,因此首先使用 NSLog 来查看它们需要的顺序):
然后传递 stringToABPropertyID: 数组
[self.allKeys objectAtIndex:j]
中的值,您将返回一个ABPropertyID
:Set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:
Replace 0x543216 with the address of the object that caused the crash, and you will get a much more useful stack trace and it should help you pinpoint the exact line in your code that is causing the problem.
- More thoughts -
If
self.allKeys
is indeedthen you should probably get the
intValue
of the array object (property) since anABPropertyID
is just atypedef int32_t
. Something like:But we would need to see the values in
self.allKeys
or how it is populated to be sure.From ABRecordRef Reference and CFTypeRef Reference
And:
- And more troubleshooting ideas -
If the above is not the case, then your crash may be caused when you cast
CFTypeRef
toNSString *
in(NSString*)ABRecordCopyValue(currentRecordRef, currentFieldProperty)
so here is a little helper function that might solve that:Then do
currentRecord = [self stringValueForCFType:ABRecordCopyValue(currentRecordRef, currentFieldProperty)];
and check to make sureself.allKeys
has an object at indexj
andself.allContacts
has an object at indexi
:Edit (regarding the comments):
To convert string of property name to its int value, you need to create the following (this probably is not be the correct order that they need to be in, so
NSLog
them first to see what order they need to be in):Then pass
stringToABPropertyID:
the value from the array[self.allKeys objectAtIndex:j]
and you will be returned anABPropertyID
:我将之前的评论作为答案发布:
我会特别考虑 currentFieldProperty 的值 - 因为它是从字典中取出的,它是一个对象,但该函数应该接收一个枚举值。也许尝试一下
I'm posting my earlier comment as an answer:
I would especially give thought to the value of currentFieldProperty - because it is taken out of a dictionary, it is an object but the function is supposed to receive an enumerated value. Maybe try
几个问题:
(ABPropertyID)[self.allKeys objectAtIndex:j]
显然是错误的。我不确定如何成为“所有属性的数组(每个属性作为字符串)”。你说的是什么字符串?你从哪里得到这个字符串?如果您正在谈论属性名称的字符串,例如@"kABPersonEmailProperty"
那么几乎不可能从中获取它的值。kABPersonEmailProperty
这样的 ABPropertyID 值不是常量。它们是变量,并且它们似乎仅在您第一次初始化地址簿后才被初始化。Several problems:
(ABPropertyID)[self.allKeys objectAtIndex:j]
is clearly wrong. I'm not sure how it's even possible to be "an array of all properties (each property as string)". What string are you talking about? Where did you get this string from? If you are talking about the string of the name of the property e.g.@"kABPersonEmailProperty"
then it would be pretty much impossible to get the value of it from that.kABPersonEmailProperty
are not constants. They are variables, and they only seem to be initialized after you initialize an address book for the first time.