1

我正在 ios 中编写一个自定义地址簿应用程序,并使用单例地址簿引用。

下面是我的操作步骤:

+ (ABAddressBookRef) sharedAddressBook
{
    static ABAddressBookRef ref = nil;
    if ( ref == nil )
    {
        ref = ABAddressBookCreate();
    }

    return ( ref );
}

step1:打开我的通讯录应用

    ABAddressBookRef addressBook = [ABAddressBook sharedAddressBook];
    ABRecordRef person = ABAddressBookGetPersonWithRecordID( addressBook, 83 );
    NSString* name= ABRecordCopyValue(person,kABPersonFirstNameProperty);
    NSLog(@"%@",name);

控制台打印“aaa”。

第2步:

退出我的应用程序(进入后台,而不是杀死),使用系统拨号器将“aaa”人名更改为“bbb”。

第三步:

打开我的应用程序(enterForeground),做同样的事情

ABAddressBookRef addressBook = [ABAddressBook sharedAddressBook];
ABRecordRef person = ABAddressBookGetPersonWithRecordID( addressBook, 83 );
NSString* name= ABRecordCopyValue(person,kABPersonFirstNameProperty);
NSLog(@"%@",name);

控制台打印“aaa”。

我的问题是

1.为什么使用旧的addressBookRef时控制台打印“aaa”而不是“bbb”?当我将 [ABAddressBook sharedAddressBook] 更改为 ABAddressBookCreate() 时,一切似乎都正常。为什么旧的 addressBookRef 无法保持最新​​?

2.我每次都需要在enterForeground 做ABAddressBookCreate() 吗?

3.我编辑人员信息时记录ID是否更改?我猜测。

4

2 回答 2

3

原因是与地址簿的交互是事务性的。请参阅文档,尤其是http://developer.apple.com/library/ios/#documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/BasicObjects.html。您可以在应用程序运行时注册以了解数据库中的更改。然后,您应该恢复或保存:

当您收到更改回调时,您可以做两件事:如果您没有未保存的更改,您的代码应该简单地恢复您的地址簿以获取最新数据...

于 2013-01-01T03:16:01.383 回答
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 需要重新分配所有 person(wrapped) 实例,但不需要重新创建它的缓存数据。

于 2013-01-23T02:35:05.473 回答