-2

I have searched through a number of these NSRangeException error threads but can't seem to find an answer to my question. Here is my error:

2015-08-15 17:28:43.793 UTK Recruiting[8794:254203] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]' *** First throw call stack:

Here is a couple of bits of code. Basically I am going through the documents directories, getting all the filenames and paths, and then I'm trying to populate UITableView with the filenames so a cell can be selected, and then that file can be attached to an email. Here are a few bits of my code:

Parses documents directory, puts all csv files in corresponding arrays.

- (void) refreshTable {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSArray *documentArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:nil];

    NSArray *csvFiles = [documentArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString *evaluatedObject, NSDictionary *bindings) {
        return [evaluatedObject hasSuffix:@".csv"];
    }]];

    self.csvFileNames = (NSMutableArray*) csvFiles;
    self.csvFilePaths = [NSMutableArray arrayWithCapacity:[csvFiles count]];

    for (NSString *fileName in csvFiles) {
        [self.csvFilePaths addObject:[documentsDirectory stringByAppendingPathComponent:fileName]];
    }



    NSLog(@"files array %@", _csvFileNames);
    NSLog(@"files array %@", _csvFilePaths);

This is the UITableView code:

- (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(@"count: %lu", (unsigned long)[self.csvFileNames count]);
    return [self.csvFileNames count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellforRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

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

    return cell;
}

After placing break points throughout my code, I've found that it crashes in the cellForRowAtIndexPath method, which is the last method in the code I posted. Something else important to note is that there are 4 csv files, and [self.csvFileNames count] correctly gives the number 4.

The code should be running until index 3, but I can't figure out why it is not.

  • thread #1: tid = 0x40646, 0x000000010de9f286 libsystem_kernel.dylib__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT frame #0: 0x000000010de9f286 libsystem_kernel.dylib__pthread_kill + 10 frame #1: 0x000000010ded242f libsystem_pthread.dylibpthread_kill + 90 frame #2: 0x000000010dc3f19a libsystem_sim_c.dylibabort + 129 frame #3: 0x000000010da2a481 libc++abi.dylibabort_message + 257 frame #4: 0x000000010da523d5 libc++abi.dylibdefault_terminate_handler() + 267 frame #5: 0x0000000106aeae19 libobjc.A.dylib_objc_terminate() + 103 frame #6: 0x000000010da4fb01 libc++abi.dylibstd::__terminate(void (*)()) + 8 frame #7: 0x000000010da4f7aa libc++abi.dylib__cxa_rethrow + 99 frame #8: 0x0000000106aead2c libobjc.A.dylibobjc_exception_rethrow + 40 frame #9: 0x0000000106d7a41e CoreFoundationCFRunLoopRunSpecific + 654 frame #10: 0x0000000109b13a3e GraphicsServicesGSEventRunModal + 161 frame #11: 0x000000010724a8c0 UIKit`UIApplicationMain + 1282
    • frame #12: 0x000000010640211f UTK Recruitingmain(argc=1, argv=0x00007fff598014f8) + 111 at main.m:14 frame #13: 0x000000010db97145 libdyld.dylibstart + 1 frame #14: 0x000000010db97145 libdyld.dylib`start + 1

bt all crash report:

  • thread #1: tid = 0x56469, 0x0000000109200286 >libsystem_kernel.dylib__pthread_kill + 10, queue = 'com.apple.main-thread', stop >reason = signal SIGABRT frame #0: 0x0000000109200286 libsystem_kernel.dylib__pthread_kill + 10 frame #1: 0x000000010923342f libsystem_pthread.dylibpthread_kill + 90 frame #2: 0x0000000108fa019a libsystem_sim_c.dylibabort + 129 frame #3: 0x0000000108d8b481 libc++abi.dylibabort_message + 257 frame #4: 0x0000000108db33d5 libc++abi.dylibdefault_terminate_handler() + 267 frame #5: 0x0000000101e4be19 libobjc.A.dylib_objc_terminate() + 103 frame #6: 0x0000000108db0b01 libc++abi.dylibstd::__terminate(void (*)()) + 8 frame #7: 0x0000000108db07aa libc++abi.dylib__cxa_rethrow + 99 frame #8: 0x0000000101e4bd2c libobjc.A.dylibobjc_exception_rethrow + 40 frame #9: 0x00000001020db41e CoreFoundationCFRunLoopRunSpecific + 654 frame #10: 0x0000000104e74a3e GraphicsServicesGSEventRunModal + 161 frame #11: 0x00000001025ab8c0 UIKit`UIApplicationMain + 1282

    • frame #12: 0x000000010176311f UTK Recruitingmain(argc=1, argv=0x00007fff5e4a04f8) + 111 at main.m:14 frame #13: 0x0000000108ef8145 libdyld.dylibstart + 1 frame #14: 0x0000000108ef8145 libdyld.dylib`start + 1

    thread #2: tid = 0x564a0, 0x0000000109201232 libsystem_kernel.dylibkevent64 + 10, queue = 'com.apple.libdispatch-manager' frame #0: 0x0000000109201232 libsystem_kernel.dylibkevent64 + 10 frame #1: 0x0000000108eb376c libdispatch.dylib_dispatch_mgr_invoke + 247 frame #2: 0x0000000108eb3511 libdispatch.dylib_dispatch_mgr_thread + 54

    thread #3: tid = 0x564a2, 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #0: 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #1: 0x00000001092316c3 libsystem_pthread.dylib_pthread_wqthread + 869 frame #2: 0x000000010922f40d libsystem_pthread.dylibstart_wqthread + 13

    thread #4: tid = 0x564a3, 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #0: 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #1: 0x00000001092316c3 libsystem_pthread.dylib_pthread_wqthread + 869 frame #2: 0x000000010922f40d libsystem_pthread.dylibstart_wqthread + 13

    thread #5: tid = 0x564a4, 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #0: 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #1: 0x00000001092316c3 libsystem_pthread.dylib_pthread_wqthread + 869 frame #2: 0x000000010922f40d libsystem_pthread.dylibstart_wqthread + 13

    thread #6: tid = 0x564a5, 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #0: 0x000000010920094a libsystem_kernel.dylib__workq_kernreturn + 10 frame #1: 0x00000001092316c3 libsystem_pthread.dylib_pthread_wqthread + 869 frame #2: 0x000000010922f40d libsystem_pthread.dylibstart_wqthread + 13

  • I'd try setting a breakpoint on the `cell.textLabel.text=...` line and using `po self.csvFileNames` to see what the array contained each time through (or use NSLog). – Phillip Mills Aug 15 '15 at 22:08
  • I would, but unfortunately the method does not appear to work it all. It crashes immediately no matter where I put the break point in the method. – Alex Cauthen Aug 15 '15 at 22:11
  • Try printing out the output of indexPath in cellForRowAtIndexPath, before anything. The crash is most likely caused by the dequeReusableCellWithIdentifer. – saagarjha Aug 15 '15 at 22:13
  • That's suspicious. When it crashes, type `bt` in your debug console and add the results to your question. – Phillip Mills Aug 15 '15 at 22:14
  • Added, I also added the print statement and set a breakpoint at it, but it did not run. – Alex Cauthen Aug 15 '15 at 22:21
  • OK, I'm confused too. The crashing thread is off handling some graphics event and nowhere near your code. One more try...what do you see if you use `bt all` instead? (Maybe something's happening in the background.) – Phillip Mills Aug 15 '15 at 22:33
  • How is `refreshTable` called? Is it possible that it is running at the same time as your table is being populated? – Paulw11 Aug 15 '15 at 23:15
  • how is your variable `csvFileNames` declared? can you post the line? – dGambit Aug 16 '15 at 01:49
  • refreshTable is called in viewDidLoad, and then it is called anytime a button is pressed to update the view. cvsFileNames is declared in the .h file as @property (strong, nonatomic) NSMutableArray *csvFileNames. – Alex Cauthen Aug 16 '15 at 22:10
  • I'll post the bt all crash report when I am back in civilization which will be tomorrow – Alex Cauthen Aug 16 '15 at 22:18
  • I've posted the bt all crash report – Alex Cauthen Aug 17 '15 at 19:36
  • I don't appreciate the down votes on my question.... – Alex Cauthen Aug 19 '15 at 13:35

2 Answers2

0

Change your cellforRowAtIndexPath method :-

static NSString *CellIdentifier = @"Cell";

    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
Waruna
  • 162
  • 8
  • It is still crashing with the same error. I don't see how this fixes the problem of the code indexing beyond the bounds. – Alex Cauthen Aug 16 '15 at 22:05
0

refreshTable appears to be building the array self.csvFilePaths correctly, but your cellForRowAtIndexPath is referencing self.csvFileNames and I don't see where that is being populated.

The range exception is telling you that you don't have 4 objects in self.csvFileNames.

To make your life a lot easier going forward, add the "All Exceptions" breakpoint to your project. Go to the Breakpoint Navigator (Command 7). At the bottom, click + and choose "Add Exception Breakpoint." When your code runs, it will break on the exception before it is thrown.

Dan Loughney
  • 4,647
  • 3
  • 25
  • 40
  • self.csvFileNames = (NSMutableArray*) csvFiles; is the line that populates self.csvFileNames, which is right above where self.csvFilePaths is populated. You'll notice that I have a print statement: NSLog(@"files array %@", _csvFileNames); it prints out the following: "Change Event Name.csv", "f.csv", "it.csv", "j.csv" It correctly prints the 4 files found in the document directories folder, so I find it hard to believe that, that is the issue. I even put a print statement above the return statement in numbersOfRowsInSection, and it prints the number 4. – Alex Cauthen Aug 18 '15 at 02:01
  • Didn't notice that. Possibly then the problem is you are casting an Array into a Mutable Array which is allowed by the compiler, but not a good idea. Try `self.csvFileNames = [NSMutableArray arrayWithArray:csvFiles];` and see what happens – Dan Loughney Aug 18 '15 at 02:09