0

I am having the following error when trying to access "MySkinsView"

2013-07-06 14:57:28.523 Skin Creator[778:907] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (0)'
*** First throw call stack:
(0x335662a3 0x3b1d997f 0x335661c5 0x334dec01 0x77741 0x353b954d 0x3539e313 0x353b57cf 0x35371803 0x3511bd8b 0x3511b929 0x3511c85d 0x3511c243 0x3511c051 0x3511beb1 0x3353b6cd 0x335399c1 0x33539d17 0x334acebd 0x334acd49 0x3705d2eb 0x353c2301 0x6b171 0x6b0f8)
libc++abi.dylib: terminate called throwing an exception

My .m is as follows:

#import "MySkinsView.h"
#import <QuartzCore/QuartzCore.h>
#import "CreateASkinView.h"
#import "SkinManipulator.h"


@interface MySkinsView ()

@end

@implementation MySkinsView{
    int deletedIndexPath;
}
@synthesize customCell, cellImage, cellLabel, array, alertView, TableView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *arrayFileName = [documentsDirectory stringByAppendingPathComponent:@"example.dat"];
    NSString *errString;
    NSData *serialized = [NSData dataWithContentsOfFile:arrayFileName];

    array =
    [NSPropertyListSerialization propertyListFromData:serialized
                                     mutabilityOption:NSPropertyListMutableContainers
                                               format:NULL
                                     errorDescription:&errString];

    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}
-(void)viewDidAppear:(BOOL)animated{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *arrayFileName = [documentsDirectory stringByAppendingPathComponent:@"example.dat"];
    NSString *errString;
    NSData *serialized = [NSData dataWithContentsOfFile:arrayFileName];

    array =
    [NSPropertyListSerialization propertyListFromData:serialized
                                     mutabilityOption:NSPropertyListMutableContainers
                                               format:NULL
                                     errorDescription:&errString];
    if (errString)
    {
        NSLog(@"%@", errString);
    }

    [super viewDidLoad];
    [TableView reloadData];
}
-(int)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [array count];
}

-(UITableViewCell* )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"cell identifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = customCell;
        self.customCell = nil;
    }
    NSArray *skinInfo=[array objectAtIndex:indexPath.row];

    cellLabel.text=[skinInfo objectAtIndex:1];
    cellLabel.font=[UIFont fontWithName:@"CurseCasualRegular" size:17];
    cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"tableviewbg.png"]];
    UIImage *skin=[UIImage imageWithData:[skinInfo objectAtIndex:0]];
    UIImage *frontView=[[SkinManipulator alloc]createFrontViewOfSkin:skin];
    cellImage.image=frontView;
    cellImage.layer.magnificationFilter=kCAFilterNearest;
    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSArray *skinInfo=[array objectAtIndex:indexPath.row];

    CreateASkinView *createASkin;
    createASkin = [[CreateASkinView alloc] initWithNibName:@"CreateASkinView" bundle:nil];
    createASkin.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    createASkin.indexPathOfSkin=indexPath.row+1;
    createASkin.skin=[UIImage imageWithData:[skinInfo objectAtIndex:0]];
    createASkin.skinName=[skinInfo objectAtIndex:1];
    [self presentViewController:createASkin animated:YES completion:nil];
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        alertView=[[UIAlertView alloc]initWithTitle:@"Are you sure you want to delete this skin?" message:nil delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil];
        deletedIndexPath=indexPath.row;
        [alertView show];
    }
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(buttonIndex == 0){
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *arrayFileName = [documentsDirectory stringByAppendingPathComponent:@"example.dat"];
        [array removeObjectAtIndex:deletedIndexPath];
        NSString *errString;
        NSData *serialized =
        [NSPropertyListSerialization dataFromPropertyList:array
                                                   format:NSPropertyListBinaryFormat_v1_0
                                         errorDescription:&errString];
        [serialized writeToFile:arrayFileName atomically:YES];
        [TableView reloadData];
    }
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)back:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}
@end

This occurs when I tap on the button that opens My Skins. Please advise if you can locate the bug.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • This is not likely a simple fix. In my experience, issues like this are usually caused by the data not importing into the array correctly. You should set a breakpoint at the array to see what it actually loads. Your array has more than one element, but there seems to be some type of corruption on those objects. When the table tries to load the second object in the array, it fails. Also, fwiw, you probably don't need to load up the array in BOTH viewDidLoad: and viewWillAppear:. Check out this answer: http://stackoverflow.com/a/1579624/1318525 – JiuJitsuCoder Jul 06 '13 at 03:45
  • Offers of payment [are not acceptable here on SO](http://meta.stackexchange.com/questions/65039/offering-monetary-incentives-to-complete-question); I've removed that sentence. If you need to hire a developer, please have a look at [Careers](http://careers.stackoverflow.com/). – jscs Jul 06 '13 at 05:05

3 Answers3

2

Well, this is most likely a simple crash caused by attempting to get the first element in an empty array. Check you lines of code that look like this one:

createASkin.skinName=[skinInfo objectAtIndex:1];

If the skinInfo NSArray contains zero elements then your code will crash like that. There are multiple places where your code calls objectAtIndex like this, so you should recheck them all to make sure this crash cannot happen.

MoDJ
  • 4,309
  • 2
  • 30
  • 65
  • This has happened after I saved 1 item. So thats not whats happening. Im not a developer so could you guide me through this fix. Or would you be able to fix this for a small fee? –  Jul 06 '13 at 03:23
  • 2
    That's actually the second element in the array. – Joel Jul 06 '13 at 03:27
  • 1
    @MichaelTopschij: Array indexes start at 0. The first element is at index 0, the second is at index 1, the third at index 2 and so on. – Chuck Jul 06 '13 at 03:51
1

There's not exactly a lot of error checking or defensive programming going on here, especially given it is importing data from a random file.

The issue is probably related to the example.dat data file (or lack thereof). Is errString being logged during viewDidAppear? Is the data file there and properly formatted? You should post the contents of example.dat.

And yes, the error is happening because you are calling an item out of bounds in the array. That is simple to solve (just put in some error checking before assessing the array), but figuring out why the array is malformed in the first place will take some investigation.

Joel
  • 15,654
  • 5
  • 37
  • 60
0

Attempting to access an element in an array which is empty . My suggestion is to check your array by consoling it .

Super Xtreem
  • 187
  • 1
  • 10