получение уведомлений при обновлении адресной книги

#ios #tableview #addressbook

#iOS #просмотр таблицы #адресная книга

Вопрос:

Я пытаюсь получать обновления от addressBook с использованием предопределенного метода

 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, self);

void addressBookChanged(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{
    NSLog(@"AddressBook Changed");
    [self getContactsFromAddressBook];
}
  

Я вызываю ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, self); в своем application:didFinishLaunchingWithOptions , затем я выполняю метод обратного вызова, как можно использовать self внутри этого метода c? как я могу обновить свой tableview, если я не могу использовать свои объекты?

Ответ №1:

Вы не можете напрямую использовать self в этой функции — но вы передаете self в качестве контекста при регистрации для обратного вызова change, поэтому он будет передан в качестве аргумента в функции addressBookChanged.

 void addressBookChanged(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{
    NSLog(@"AddressBook Changed");
    YourClass *yourInstance = (__bridge YourClass *)(context)
    [yourInstance getContactsFromAddressBook];
}
  

чтобы быть более конкретным для ваших классов —

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
{
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, self.wkListVC);     
    return YES; 
}

void addressBookChanged(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) 
{     
    NSLog(@"AddressBook Changed");     
    wbkABViewControllerTableViewController *myVC = (__bridge wbkABViewControllerTableViewController *)context;
    [myVC getPersonOutOfAddressBook]; 
}
  

Убедитесь сами.wkListVC не равен нулю, когда вы регистрируетесь для обратного вызова изменения.

Комментарии:

1. и я создаю свой контекст, который отправляю в функции обратного вызова ((__bridge void*) myClass) ? когда я это делаю, я обнаруживаю, что мой контекст равен нулю, поэтому я не получаю объект. Я делаю что-то не так?

2. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, (__bridge void *)self.wkListVC); return YES; }

3. void addressBookChanged(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { NSLog(@"AddressBook Changed"); wbkABViewControllerTableViewController *myVC = (__bridge wbkABViewControllerTableViewController *)context; [myVC getPersonOutOfAddressBook]; }

4. Хорошо, теперь мы подходим к сути моей проблемы, я не могу отправить self.wkListVC в качестве параметра, там по-прежнему написано — необъявленный идентификатор «self» — , решение, предлагаемое отладчиком Xcode, заключается в том, чтобы поместить (__bridge void *) перед ним, и когда я это делаю, это не работает. Есть идеи?

5. Извините, моя ошибка. Вам действительно нужно выполнить приведение self.wkListVC с помощью (__bridge void *) — но если в функции addressBookChanged его значение равно нулю, то либо оно было равно нулю, когда вы передавали его в качестве аргумента ABAddressBookRegisterExternalChangeCallback, либо вы разыменовали его с момента регистрации для обратного вызова. Попробуйте использовать ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, (__bridge void *)self); а затем wbkAppDelegate *appDelegate = (__bridge wbkAppDelegate *)context в функции обратного вызова. Затем вы можете отключить свой контроллер просмотра от этого.