Ios 从ABAddressBookRequestAccessWithCompletion()获取联系人数组时,给出的值为零

Ios 从ABAddressBookRequestAccessWithCompletion()获取联系人数组时,给出的值为零,ios,objective-c,cocoa-touch,abaddressbook,Ios,Objective C,Cocoa Touch,Abaddressbook,我正在尝试使用NSLog()将手机的所有联系人打印到控制台。当前此代码正在打印(null) .h @property (nonatomic, strong) NSMutableArray *contactsObjects; .m @synthesize contactsObjects; //lazy instantiation. - (NSMutableArray *)contactsObjects { if(!contactsObjects) { conta

我正在尝试使用
NSLog()
将手机的所有联系人打印到控制台。当前此代码正在打印
(null)

.h

@property (nonatomic, strong) NSMutableArray *contactsObjects;
.m

@synthesize contactsObjects;
//lazy instantiation. 
- (NSMutableArray *)contactsObjects
{
    if(!contactsObjects)
    {
        contactsObjects = [[NSMutableArray alloc]init];
    }

    return contactsObjects;
}

- (void)viewWillAppear:(BOOL)animated
{
    CFErrorRef error = nil;

    // Request authorization to Address Book
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &error);

    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
            if (granted) {
                // First time access has been granted, add all the user's contacts to array.
                CFMutableArrayRef contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
            } else {
                // User denied access.
                // Display an alert telling user that they must allow access to proceed to the "invites" page.
            }
        });
    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        // The user has previously given access, add all the user's contacts to array.
        CFMutableArrayRef contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
    }
    else {
        // The user has previously denied access
        // Send an alert telling user that they must allow access to proceed to the "invites" page.
    }

    NSLog(@"%@", contactsObjects);
}
我在这里得到两个警告:

我不知道我应该怎么做才能正确地将联系人的姓名和号码打印到控制台上


如何打印我的联系人姓名和号码?

您说它打印为空,并且您得到了一个错误。但这可以解释你的错误

contactObjects
在if块和else if块中定义。所以当你在你的条件之外的时候,它就不再被定义了

试试这个

- (void)viewWillAppear:(BOOL)animated
{
    CFErrorRef error = nil;

    // Request authorization to Address Book
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &error);

    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
            if (granted) {
                // First time access has been granted, add all the user's contacts to array.
                contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
            } else {
                // User denied access.
                // Display an alert telling user that they must allow access to proceed to the "invites" page.
            }
        });
    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        // The user has previously given access, add all the user's contacts to array.
        contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
    }
    else {
        // The user has previously denied access
        // Send an alert telling user that they must allow access to proceed to the "invites" page.
    }

    NSLog(@"%@", contactsObjects);
}

你说它输出空值,然后你得到一个错误。但这可以解释你的错误

contactObjects
在if块和else if块中定义。所以当你在你的条件之外的时候,它就不再被定义了

试试这个

- (void)viewWillAppear:(BOOL)animated
{
    CFErrorRef error = nil;

    // Request authorization to Address Book
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &error);

    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
            if (granted) {
                // First time access has been granted, add all the user's contacts to array.
                contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
            } else {
                // User denied access.
                // Display an alert telling user that they must allow access to proceed to the "invites" page.
            }
        });
    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        // The user has previously given access, add all the user's contacts to array.
        contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
    }
    else {
        // The user has previously denied access
        // Send an alert telling user that they must allow access to proceed to the "invites" page.
    }

    NSLog(@"%@", contactsObjects);
}

您的代码存在范围问题。
视图中的
contactsObjects
变量将出现:
与您调用的
contactsObjects
的ivar无关。您正在声明使用相同名称的新变量。另一方面,末尾的
NSLog()
是ivar。但是设置这些其他变量并没有将任何内容放入ivar,因此您可以看到
(null)
,这就是
NSLog()
表示“无对象”的方式

通过使用ivar而不是新的变量声明来解决这个问题

if (granted) {
    contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);

else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
    contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
您还需要铸造这些:

    contactsObjects = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBookRef);
(此外,该函数不返回可变数组,因此您可能会遇到麻烦。)


第二个问题是
ABAddressBookRequestAccessWithCompletion()
不会停止并等待其完成块运行。当请求访问时,方法的其余部分将继续进行,因此在实际设置
联系人对象之前,您将到达
NSLog()

您的代码存在范围问题。
视图中的
contactsObjects
变量将出现:
与您调用的
contactsObjects
的ivar无关。您正在声明使用相同名称的新变量。另一方面,末尾的
NSLog()
是ivar。但是设置这些其他变量并没有将任何内容放入ivar,因此您可以看到
(null)
,这就是
NSLog()
表示“无对象”的方式

通过使用ivar而不是新的变量声明来解决这个问题

if (granted) {
    contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);

else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
    contactsObjects = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
您还需要铸造这些:

    contactsObjects = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBookRef);
(此外,该函数不返回可变数组,因此您可能会遇到麻烦。)



第二个问题是
ABAddressBookRequestAccessWithCompletion()
不会停止并等待其完成块运行。当请求访问时,方法的其余部分将继续进行,因此在实际设置
联系人对象之前,您将到达
NSLog()

视图中将出现另一个警告:
关于隐藏ivar?或者一个未声明的变量指向setter的错误?实际上我不知道。这两个错误是“黄色”错误,它们只是针对我上面发布的错误。您使用的是什么版本的Xcode?您是否显式合成了
contactsObjects
?我不确定显式合成是什么,但我已经合成了它:
@synthesis contactsObjects这是显式合成,是的。
视图中将出现另一个警告:
关于阴影ivar?或者一个未声明的变量指向setter的错误?实际上我不知道。这两个错误是“黄色”错误,它们只是针对我上面发布的错误。您使用的是什么版本的Xcode?您是否显式合成了
contactsObjects
?我不确定显式合成是什么,但我已经合成了它:
@synthesis contactsObjects这是显式合成,是的。
联系人对象
几乎肯定不应该在这里局部声明;我很确定OP只是想把它放到ivar里。除此之外,就是这样。对不起,我一定是对我自己的错误视而不见,但我甚至看不到你我的代码有任何变化。你介意指出你到底在哪里做了更改吗?是的,正如@JoshCaswell提到的,你可能会把它放在函数之外(或者作为返回值),但这是解释错误的最简单方法。这实际上只是导致了另一个错误。使用
CFMutableArrayRef联系人对象
added,建议将变量设置为NULL,看起来像
CFMutableArrayRef contactsObjects=NULL
在没有或启动NULL时,错误仍然存在。
视图中没有返回值将出现:
(另外,请注意这是一个警告,不是错误。)只需删除本地声明
CFMutableArrayRef contactsObjects
然后在
视图中出现对
contactsObjects
的两个引用:
是ivar,这正是您试图做的,@WhiteHatPrince.
contactsObjects
几乎肯定不应该在这里本地声明;我很确定OP只是想把它放到ivar里。除此之外,就是这样。对不起,我一定是对我自己的错误视而不见,但我甚至看不到你我的代码有任何变化。你介意指出你到底在哪里做了更改吗?是的,正如@JoshCaswell提到的,你可能会把它放在函数之外(或者作为返回值),但这是解释错误的最简单方法。这实际上只是导致了另一个错误。使用
CFMutableArrayRef联系人对象
added,建议将变量设置为NULL,看起来像
CFMutableArrayRef contactsObjects=NULL没有或有空启动,错误仍然存在。没有来自