简体   繁体   中英

UITableView crashes on scrolling

I am facing a problem in table view, the application crashes as soon as i scrolldown and try to select a row. Error I am getting in console is

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

Please help me to understand why i am getting this error, I dont think there is any nil element in my array, let me show you the code

I have created a SelectContactViewController in which a user can select number of contact so the files are

SelectContactController.h

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>



@interface SelectContactController :UIViewController
<UITableViewDataSource, UITableViewDelegate>
{
    NSArray *selectedImageIds;
    NSArray *selectContacts;
}
@property (nonatomic, retain) NSArray *selectContacts;

and the implementation file SelectContactController.m

#import "SelectContactController.h"



@interface SelectContactController ()

@end

@implementation SelectContactController
@synthesize selectContacts;
- (void)viewDidLoad
{
    [super viewDidLoad];


    selectContacts = [[NSArray alloc] init];
    selectedRows = [[NSMutableArray alloc] init];
    contactDictionary = [[NSMutableDictionary alloc] init];


    id appDelegate = (id)[[UIApplication sharedApplication] delegate];
    managedObjectContext = [appDelegate managedObjectContext];
    selectedImageIds = [appDelegate selectedImageIds];



    [self getAddressbookData];


}
#pragma mark - Address book Methods

-(void)getAddressbookData
{
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
    ABAddressBookRef addressBook = ABAddressBookCreate();
#else
    CFErrorRef *error = nil;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
#endif

    NSArray * people;


    BOOL accessGranted = [self __addressBookAccessStatus:addressBook];

    if (accessGranted) {

        people = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
        // Do whatever you need with thePeople...

    }
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    NSMutableArray *contactArray = [[NSMutableArray alloc] init];



    for (CFIndex i = 0; i < nPeople; i++) {
        ABRecordRef record = CFArrayGetValueAtIndex((__bridge CFArrayRef)(people), i);
        NSString *firstName = (__bridge NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty);
        NSString *lastName = (__bridge NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty);
        NSString *fullName = nil;



        if (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst)
            fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
        else
            fullName = [NSString stringWithFormat:@"%@, %@", lastName, firstName];

        [contactArray addObject:fullName];

        //
        // Phone Numbers
        //
        ABMutableMultiValueRef phoneNumbers = ABRecordCopyValue(record, kABPersonPhoneProperty);
        CFIndex phoneNumberCount = ABMultiValueGetCount( phoneNumbers );


        NSMutableArray *numbersArray = [[NSMutableArray alloc] init];
        for ( CFIndex k=0; k<phoneNumberCount; k++ )
        {
            CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex( phoneNumbers, k );
            CFStringRef phoneNumberValue = ABMultiValueCopyValueAtIndex( phoneNumbers, k );
            CFStringRef phoneNumberLocalizedLabel = ABAddressBookCopyLocalizedLabel( phoneNumberLabel );
            // converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"

            // Find the ones you want here
            //
           // NSLog(@"-----PHONE ENTRY -> name:%@ :  %@ : %@", fullName, phoneNumberLocalizedLabel, phoneNumberValue );
            [numbersArray addObject:CFBridgingRelease(phoneNumberValue)];

            CFRelease(phoneNumberLocalizedLabel);
            CFRelease(phoneNumberLabel);
            CFRelease(phoneNumberValue);
        }

       // NSLog(@"phone numbers %@", numbersArray);
        [contactDictionary setObject:numbersArray forKey:fullName];

        CFRelease(record);

    }

    selectContacts = contactArray;
   // NSLog(@"dictionary of array %@", contactDictionary);

    //NSLog(@"contacts count %d", [selectContacts count]);
}

-(BOOL)__addressBookAccessStatus:(ABAddressBookRef) addressBook
{
    __block BOOL accessGranted = NO;

    if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);

        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            accessGranted = granted;
            dispatch_semaphore_signal(sema);
        });

        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        // dispatch_release(sema);
    }
    else { // we're on iOS 5 or older
        accessGranted = YES;
    }
    return accessGranted;
}



#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    NSLog(@"select content count %d", [selectContacts count]);
    return [selectContacts count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    cell.textLabel.text = [self.selectContacts objectAtIndex:indexPath.row];


    return cell;
}

Please help me to resolve this issue

The exception message is quite clear: You are trying to insert a nil value into an array. The bug is probably in the line

[numbersArray addObject:CFBridgingRelease(phoneNumberValue)];

Check if phoneNumberValue is nil before adding the object. Another good idea is to use the debugger to find the problem. Add an exception breakpoint before running the app in Xcode.

i think in this case debugging would be good solution. So use break point on this line and let me know in which index it is crashing.

   cell.textLabel.text = [self.selectContacts objectAtIndex:indexPath.row];

With selectContacts = [[NSArray alloc] init]; or selectContacts = contactArray; the setter is not used. It should be either self.selectContacts when assigning or do @synthesize selectContacts = _selectContacts; and then use only _selectContacts only within the .m file.

It may be possible that for few numbers you have not provided the first name and last name details so you must try this :

if (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst)

        fullName = [[NSString alloc]initWithFormat:@"%@ %@", firstName, lastName];
     else
       fullName = [[NSString alloc]initWithFormat:@"%@, %@", lastName, firstName];
  if([fullName length]>0)

        [contactArray addObject:fullName];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM