objective-c完成阻止问题

时间:2014-12-18 08:33:15

标签: ios objective-c objective-c-blocks

我正在尝试在异步任务中获取JSON (NSString *)地址簿,但是我希望它与异步和完成块一起使用。

我已经设法在没有完成块的情况下检索那个简单,但是当我添加完成块时,我有以下编译器错误:

传递NSString *(^)(bool, CFErrorRef)' to parameter of type 'ABAddressBookRequestAccessCompletionHandler' (aka 'void (^)(bool, CFErrorRef)')

的块指针类型不兼容

这是我的代码

+ (NSString *) getAddressBook:(id (^)())block {
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();

if (status == kABAuthorizationStatusDenied)
{
    // if you got here, user had previously denied/revoked permission for your
    // app to access the contacts, and all you can do is handle this gracefully,
    // perhaps telling the user that they have to go to settings to grant access
    // to contacts
    [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
    return nil;
}
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

if (error)
{
    NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
    if (addressBook) CFRelease(addressBook);
    return nil;
}

if (status == kABAuthorizationStatusNotDetermined)
{
    // present the user the UI that requests permission to contacts ...
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) -> THE ERROR OCCURS HERE !
                                             {...

我认为问题出在我的完成块之内,但我无法找到一些很好的示例/教程来解决我的具体问题。如果有一些人可以帮助我,我会很高兴。

1 个答案:

答案 0 :(得分:2)

你的问题是你正在声明这样的getAddressBook(如果我们剥离块)

-(id)block

并且您尝试将其作为类型函数传递:

-(void)block:(BOOL)aBool error:(CFErrorRef*)error

块很难用到语法(在swift中有所改进)但是我总是在不确定的时候引用这个网站:

block syntax reference

更新:

您必须等待异步方法完成。您也可以参考official documentation

+ (void) getAddressBook:((^)(NSString* result))block {
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();

    if (status == kABAuthorizationStatusDenied)
    {
        // if you got here, user had previously denied/revoked permission for your
        // app to access the contacts, and all you can do is handle this gracefully,
        // perhaps telling the user that they have to go to settings to grant access
        // to contacts
        [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
        block(nil);
    }
    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

    if (error)
    {
        NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
        if (addressBook) CFRelease(addressBook);
        block(nil);
    }

    if (status == kABAuthorizationStatusNotDetermined)
    {


        // present the user the UI that requests permission to contacts ...
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) -> THE ERROR OCCURS HERE !
                                                 {
                                                     NSString* result = whatever

                                                     block(result);
                                                 });
    }
}

并像这样使用它:

[YourClass getAddressBook:^(NSString* result)
 {
     //now you really have result
 }];