为什么地址簿无法与ios保持同步?

时间:2013-01-01 03:02:11

标签: iphone ios addressbook

我在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是否已更改?我怀疑。

2 个答案:

答案 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需要重新分配所有人(包装)实例,但不需要重新创建它的缓存数据。