iPhone - 地址簿搜索崩溃

时间:2011-12-11 10:06:08

标签: iphone objective-c ios ios5 abaddressbook

我们的一些应用商店用户在搜索地址簿时报告了崩溃。 我很失落,因为我无法重现这个问题。

enter image description here

我如何查询地址簿有什么问题吗?谢谢!

+ (NSDictionary *) scanAddressBook
{
    #if TARGET_OS_IPHONE
    NSUInteger i;
    CFIndex index;

    ABAddressBookRef addressBook = ABAddressBookCreate();
    NSArray *people = (NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);

    if ( people==nil || (people && ([people count] == 0)))
    {
        TRACE_LOG(@"scanAddressBook ", @"NO ADDRESS BOOK ENTRIES TO SCAN");
        if(people) [people release];
        CFRelease(addressBook);
        return nil;
    }

    NSMutableArray *numbersArray = [NSMutableArray new];
    NSMutableArray *mailsArray = [NSMutableArray new];

    for ( i=0; i<[people count]; i++ )
    {
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

        ABRecordRef person = (ABRecordRef)[people objectAtIndex:i];

        NSMutableDictionary *phoneDictionary = [NSMutableDictionary new];

        CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
        CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);

        NSString* log =[NSString stringWithFormat:@"-----CONTACT ENTRY -> %@ : %@", firstName, lastName ];
        TRACE_LOG(@"scanAddressBook",log);


        NSString *userName = @"NoName";
        if (firstName && lastName)
            userName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
        else if (firstName)
            userName = [NSString stringWithFormat:@"%@", firstName];
        else if (lastName)
            userName = [NSString stringWithFormat:@"%@", lastName];

        if(firstName) CFRelease(firstName);
        if(lastName) CFRelease(lastName);
        //
        // Phone Numbers
        //
        ABMutableMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
        CFIndex phoneNumberCount = ABMultiValueGetCount( phoneNumbers );

        for ( index=0; index<phoneNumberCount; index++ )
        {
            CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex( phoneNumbers, index);
            CFStringRef phoneNumberValue = ABMultiValueCopyValueAtIndex( phoneNumbers, index);
            CFStringRef phoneNumberLocalizedLabel = ABAddressBookCopyLocalizedLabel( phoneNumberLabel );    
            // converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"
            // Find the ones you want here
            //

            NSString* log =[NSString stringWithFormat:@"-----PHONE ENTRY -> %@ : %@", phoneNumberLocalizedLabel, phoneNumberValue ];
            TRACE_LOG(@"scanAddressBook",log);

            if (![NetworkingUtils validatePhoneNumber:(NSString *)phoneNumberValue]) {
                NSLog(@"invalid phone number: %@",phoneNumberValue);
                CFRelease(phoneNumberLocalizedLabel);
                CFRelease(phoneNumberLabel);
                CFRelease(phoneNumberValue);
                continue;
            }

            [phoneDictionary setObject:(NSString *)phoneNumberValue forKey:InviteUserDataNumberKeyID];
            [phoneDictionary setObject:(NSString *)phoneNumberLocalizedLabel forKey:InviteUserDataNumberTypeKeyID];
            [phoneDictionary setObject:(NSString *)userName forKey:InviteUserDataNameTypeKeyID];

            CFRelease(phoneNumberLocalizedLabel);
            CFRelease(phoneNumberLabel);
            CFRelease(phoneNumberValue);
            NSMutableDictionary *copyPhoneDict = [phoneDictionary copy];
            [numbersArray addObject:copyPhoneDict];
            [copyPhoneDict release];
        }
        CFRelease(phoneNumbers);
        [phoneDictionary release];

        NSMutableDictionary *mailDictionary = [NSMutableDictionary new];
        ABMutableMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
        CFIndex mailsNumberCount = ABMultiValueGetCount( emails );
        for ( index=0; index < mailsNumberCount; index++ )
        {
            CFStringRef emailValue = ABMultiValueCopyValueAtIndex( emails,index);
            // converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"
            // Find the ones you want here
            //
            NSString* log =[NSString stringWithFormat:@"-----EMAIL ENTRY -> : %@", emailValue ];
            TRACE_LOG(@"scanAddressBook",log);



            if (![NetworkingUtils validateEmail:(NSString *)emailValue]) {
                NSLog(@"invalid email address: %@",(NSString *)emailValue);
                if (emailValue) {
                    CFRelease(emailValue);
                }
                continue;
            }

            [mailDictionary setObject:(NSString *)emailValue forKey:InviteUserDataMailKeyID];
            [mailDictionary setObject:(NSString *)@"email" forKey:InviteUserDataMailTypeKeyID];
            [mailDictionary setObject:(NSString *)userName forKey:InviteUserDataMailOwnerKeyID];

            if (emailValue) {
                CFRelease(emailValue);
            }

            NSMutableDictionary *copyMailDict = [mailDictionary copy];
            [mailsArray addObject:copyMailDict];
            [copyMailDict release];
        }
        if(emails) CFRelease(emails);
        [mailDictionary release];


        [pool drain];
    }

    NSString *countryCode = [[NSUserDefaults standardUserDefaults] objectForKey:RequestUserCountryCodeKeyID];
    if (!countryCode) {
        NSLocale *locale = [NSLocale currentLocale];
        NSString *aCode = [locale objectForKey: NSLocaleCountryCode];
        countryCode = [[NetworkingUtils codesByCountryCode] objectForKey:aCode];
    }

    NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [[numbersArray copy] autorelease], InviteUsersNumbersArrayKeyID, 
                                 [[mailsArray copy] autorelease], InviteUsersMailsArrayKeyID,
                                 countryCode, RequestUserCountryCodeKeyID, nil];

    [numbersArray release];
    [mailsArray release];

    [people release];
    CFRelease(addressBook);

    return aDictionary;
#else 
    return nil ;
#endif
}

1 个答案:

答案 0 :(得分:3)

如果您提供CFRelease()值,

NULL将崩溃。我看到您的大多数CFRelease()来电都会检查NULL,但不是全部。{/ p>

其中一个很可能是触发了崩溃?

我对ABAddressBook不太熟悉,所以不知道他们会在什么情况下返回NULL

在相关的说明中,Objective-C的-release方法不会在nil上崩溃,因此您也可以将if(people) [people release];改为[people release];,因为所有方法都在如果发送到nil,Objective-C将默默无效。