1

私は iOS でカスタム アドレス帳アプリを作成しており、シングルトンの addressbookRef を使用しています。

ここに私の操作手順があります:

+ (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:

アプリを終了し(kill ではなく、enterBackground に入る)、システム ダイヤラーを使用して「aaa」の人名を「bbb」に変更します。

ステップ3:

アプリを開き(enterForeground)、同じことを行います

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

コンソール出力「aaa」。

私の質問は

1. 古い addressBookRef を使用すると、コンソールが「bbb」ではなく「aaa」を出力するのはなぜですか? [ABAddressBook sharedAddressBook] を ABAddressBookCreate() に変更すると、すべて問題ないようです。古い addressBookRef を最新の状態に保つことができないのはなぜですか?

2.enterForeground で毎回 ABAddressBookCreate() を実行する必要がありますか?

3.個人情報を編集すると、recordID は変更されますか? 私は疑います。

4

2 に答える 2

3

その理由は、アドレス帳とのやり取りがトランザクションであるためです。ドキュメント、特にhttp://developer.apple.com/library/ios/#documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/BasicObjects.htmlを参照してください。アプリの実行中にデータベースの変更について聞くために登録するのは、あなた次第です。次に、元に戻すか保存する必要があります。

変更のコールバックを受け取ったときにできることは 2 つあります。保存されていない変更がない場合は、コードでアドレス帳を元に戻して、最新のデータを取得する必要があります...

于 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! reloadAddressbook は、すべての person(ラップされた) インスタンスを再割り当てする必要がありますが、キャッシュ データを再作成する必要はありません。

于 2013-01-23T02:35:05.473 に答える