我在ios中编写自定义地址簿应用程序,并使用单例地址簿参考。
这是我的操作步骤:
+ (ABAddressBookRef) sharedAddressBook
{
static ABAddressBookRef ref = nil;
if ( ref == nil )
{
ref = ABAddressBookCreate();
}
return ( ref );
}
步骤1: 打开我的地址簿应用
ABAddressBookRef addressBook = [ABAddressBook sharedAddressBook];
ABRecordRef person = ABAddressBookGetPersonWithRecordID( addressBook, 83 );
NSString* name= ABRecordCopyValue(person,kABPersonFirstNameProperty);
NSLog(@"%@",name);
console print“aaa”。
步骤2:
退出我的应用(enterBackground,而不是kill),使用系统拨号程序将“aaa”人名更改为“bbb”。
步骤3:
打开我的应用程序(enterForeground),做同样的事情
ABAddressBookRef addressBook = [ABAddressBook sharedAddressBook];
ABRecordRef person = ABAddressBookGetPersonWithRecordID( addressBook, 83 );
NSString* name= ABRecordCopyValue(person,kABPersonFirstNameProperty);
NSLog(@"%@",name);
console print“aaa”。
我的问题是
1.为什么控制台在使用旧的addressBookRef时打印“aaa”而不是“bbb”?当我将[ABAddressBook sharedAddressBook]更改为ABAddressBookCreate()时,一切似乎都没问题。为什么旧的addressBookRef无法保持最新状态?
2.我每次都需要在enterForeground上做ABAddressBookCreate()吗?
3.编辑人员信息时,记录ID是否已更改?我怀疑。
答案 0 :(得分:3)
原因是与地址簿的交互是交易性的。请参阅文档,尤其是http://developer.apple.com/library/ios/#documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/BasicObjects.html。您可以注册以在应用程序运行时了解数据库中的更改。然后你应该还原或保存:
当您收到更改回调时,您可以执行以下两项操作:如果您没有未保存的更改,则您的代码应该只是还原您的地址簿以获取最新数据...
答案 1 :(得分:0)
static void _ExternalChangeCallback( ABAddressBookRef bookRef, CFDictionaryRef info, void * context )
{
HMAddressBook * hmAddressBook = (HMAddressBook *)context;
[hmAddressBook _resetSharedRef];
}
@implementation HMAddressBook
@synthesize addressBookRef = _ref;
+ (HMAddressBook *)sharedAddressBook
{
static HMAddressBook * volatile __shared = nil;
if ( __shared == nil )
{
HMAddressBook * tmp = [[HMAddressBook alloc] init];
if ( OSAtomicCompareAndSwapPtr(nil, tmp, (void * volatile *)&__shared) == false )
[tmp release];
}
return ( __shared );
}
- (void)_resetSharedRef
{
if (_ref != NULL)
{
ABAddressBookUnregisterExternalChangeCallback(_ref, _ExternalChangeCallback, self);
CFRelease(_ref);
}
_ref = ABAddressBookCreate();
ABAddressBookRegisterExternalChangeCallback(_ref, _ExternalChangeCallback, self);
if(_delegate && [_delegate respondsToSelector:@selector(addressBookDidResetSharedRef:)])
{
[_delegate addressBookDidResetSharedRef:self];
}
}
- (void)addressBookDidResetSharedRef:(HMAddressBook *)addressBook
{
NSLog(@"addressBookDidReset");
[self reloadAddressBookData_async:^(BOOL finished) {
[completionBlock reloadData];
}];
}
现在我在_ExternalChangeCallback时重新加载addressbook异步! reloadAddressbook需要重新分配所有人(包装)实例,但不需要重新创建它的缓存数据。