在尝试修复NSRangeException错误

时间:2018-06-14 05:41:36

标签: ios objective-c

我发现了一个错误:

  

致命异常:NSRangeException   *** - [__ NSArrayI objectAtIndex:]:索引1330超出界限[0 .. 1329]

字符串

NSArray *currentABRecords = [ApplicationPhoneDirectory records];

ApplicationPhoneDirectoryNSObject,具有唯一的联系人(字典和数组)。

但我认为错误是关于使用内存,如何更正确地管理它以避免出现这样的问题?

或者,如果我不正确,我可以将records部分放在那里。

UPD:

static NSArray *RecordsForABInterval(UInt32 start, UInt32 end, CFArrayRef allPeople) {
    NSMutableArray *peoples = [NSMutableArray arrayWithCapacity:(end - start) * 2];
    for (int i = (int) start; i < end; i++) {
        ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
        NSString *firstName = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
        NSString *lastName = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
        NSString *fullName = [NSString stringWithFormat:@"%@ %@",
                              firstName.length > 0 ? firstName : @"",
                              lastName.length > 0 ? lastName : @""];
        fullName = [fullName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

        ABMutableMultiValueRef phoneList = ABRecordCopyValue(person, kABPersonPhoneProperty);
        CFIndex phonesCount = ABMultiValueGetCount(phoneList);
        for (int j = 0; j < phonesCount; ++j) {
            CFTypeRef ABphone = ABMultiValueCopyValueAtIndex(phoneList, j);
            NSString *phone = (NSString *)CFBridgingRelease(ABphone);
            NSString *phoneInSMFormat = [phone phoneNumberInSMFormat];
            if ([phoneInSMFormat isValidSMPhoneNumber]) {
                    NSDictionary *record = @{
                                             @"name" : fullName,
                                             @"phone" : phoneInSMFormat,
                                             @"original" : phone
                                             };
                [peoples addObject:record];
            }
        }
        if (phoneList != NULL) {
            CFRelease(phoneList);
        }
    }
    return peoples;
}

+ (NSArray *)records {
    const int MaxAutoreleaseStep = 500;
    NSMutableArray *records = [NSMutableArray array];
    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

    __block BOOL accessGranted = NO;
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                accessGranted = granted;
            });
        });
    } else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        // The user has previously given access, add the contact
        accessGranted = YES;
    }
    else {
        // The user has previously denied access
        // Send an alert telling user to change privacy setting in settings app
        if (addressBook != NULL) {
            CFRelease(addressBook);
        }

        return nil;
    }

    // TODO: review this logic - should it be a single call to AB?
    if (addressBook != NULL) {
        CFRelease(addressBook);
    }

    if (accessGranted) {
        ABAddressBookRef addressbook = ABAddressBookCreateWithOptions(NULL, &error);
        if (error != NULL) {
            if (addressbook != NULL) {
                CFRelease(addressbook);
            }
            return nil;
        }

        CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressbook);
        CFIndex peopleCount = ABAddressBookGetPersonCount(addressbook);
        for (int start = 0; start < peopleCount; start += MaxAutoreleaseStep) {
            @autoreleasepool {
                int end = start + MaxAutoreleaseStep;
                NSArray *contactListCut = RecordsForABInterval((UInt32) start, (UInt32) MIN((int)peopleCount, end), allPeople);
                [records addObjectsFromArray:contactListCut];
            }
        }

        if (allPeople != NULL) {
            CFRelease(allPeople);
        }
        if (addressbook != NULL) {
            CFRelease(addressbook);
        }
    }

    return records;
}

UPD2:

- (NSString *)phoneNumberInSMFormat {
    NSString *phone = [self numericPresentation];
    if (phone.length > 0 && [phone characterAtIndex:0] == '8') {
        NSMutableString *modifiedString = [phone mutableCopy];
        [modifiedString replaceCharactersInRange:NSMakeRange(0, 1) withString:@"7"];
        phone = modifiedString;
    }
    return phone;
}
- (BOOL)isValidSMPhoneNumber {
    static NSCharacterSet *characterSet = nil;
    if (characterSet == nil) {
        characterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    }
    if ([self rangeOfCharacterFromSet:characterSet].location != NSNotFound) {
        return NO;
    }
    if (self.length < 7 || self.length > 12) {
        return NO;
    }

    return [self characterAtIndex:0] != '8';
}

0 个答案:

没有答案