1

I have a drawing app where paths are saved when the user draws and loaded back in when the user closes and re-opens the app.

I am adding objects (the brush colours) to an NSMutableArray then saving them like so:

// Adding object to NSMutableArray (this is in touchesMoved)
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:self.brushColor];
[self.brushColours addObject:colorData];

// Saving array (this is in touchesEnded)
[defaults setObject:self.brushColours forKey:[NSString stringWithFormat:@"%@BrushColours%@", currentid, pageno]];
[defaults synchronize];

That's all fine and dandy, but when I try to load the paths back in and set their colours, this happens:

Why is this happening?

Edit: I'm loading the colours back in like this (this is in a for loop for each path):

NSMutableArray *arr3 = [defaults objectForKey:[NSString stringWithFormat:@"%@BrushColours%@", currentid, pageno]];
self.brushColor = [NSKeyedUnarchiver unarchiveObjectWithData:[arr3 objectAtIndex:index]];
James Anderson
  • 556
  • 3
  • 16
  • 41
  • Where is `index` coming from? You need to verify that it's less than `[arr3 length]`. – Adam Rosenfield Nov 09 '12 at 20:57
  • Maybe this will help you: http://stackoverflow.com/questions/9756861/unable-to-save-nsmutablearray-of-my-class-to-file-ios – IluTov Nov 09 '12 at 20:57
  • What is index in your last piece of code? It crashes because it tries to load the item 634 in an array of 634 items. Remember NSArrays are 0-indexed. Without knowing where this index is coming from I can not tell more, but I guess the problem is just that value. – LocoMike Nov 09 '12 at 20:58
  • Are you using `NSUserDefaults` to save the data? I don't think that is a good idea for the large amount of data you are trying to save. – msgambel Nov 09 '12 at 20:59
  • 1
    Without knowing where does ''index'' come from, we are unable to tell why it is crashing. Good point by LocoMike - don't forget that arrays go like "0,1,2...". Maybe putting index-1 in there would solve the problem. – Dominik Hadl Nov 09 '12 at 21:00
  • Here's the first part of that for loop (including where the index comes from): http://pastie.org/5352998 – James Anderson Nov 09 '12 at 21:01
  • @DominikHadl I tried that: http://pixelbit.in/Knip – James Anderson Nov 09 '12 at 21:03

1 Answers1

2

index is the index of the object path in newpaths, but you are using this index to access to an object in arr3, not in newpaths.Are you sure that the newpaths array have the same length or arr3? Do some assertions before doing that:

NSAssert([arr3 count]>=[newpaths count], @"newpaths is longer than arr2");

This before the loop.Probably this assertion will be not true because as your exception says, index is out of arr3 bounds, unless you somehow modify the arr3 array inside the loop.
Test arr3 before accessing to it's elements:

NSAssert(index<[arr3 count], @"Index out of bounds");
NSMutableArray *arr3 = [defaults objectForKey:[NSString stringWithFormat:@"%@BrushColours%@", currentid, pageno]];
self.brushColor = [NSKeyedUnarchiver unarchiveObjectWithData:[arr3 objectAtIndex:index]];

For sure an assertion will fail and you'll know more exactly (but not totally exactly) what's wrong.By investigating again you could get the reason of the bug (also post more code if you can't achieve this alone).

EDIT

Alternative solution: It's not clear what you're trying to do, but I suppose that you want to find that object in arr3 and to unarchive it.
So you can use indexOfObject:

id obj= [newpaths objectAtIndex: index];
NSUInteger validIndex=[arr3 indexOfObject: obj];
if(validIndex!= NSNotFound)
    self.brushColor = [NSKeyedUnarchiver unarchiveObjectWithData:[arr3 objectAtIndex: validIndex]];

PS: Anyway you could directly unarchive obj, unless the objects result equal (isEqual method) but after the comparison you somehow changed the state of the object.

Ramy Al Zuhouri
  • 21,580
  • 26
  • 105
  • 187
  • Hi, I'm getting these errors when I try to implement `NSAssert`: http://pixelbit.in/Kpcm. Why is this? – James Anderson Nov 10 '12 at 09:03
  • Sorry, I forgot the second parameter of the macro: a description that will be logged in the case that the assertion fails.I'll add it now.After seeing the logs you'll be able to tell us more exactly what's wrong. – Ramy Al Zuhouri Nov 10 '12 at 12:39
  • Thanks. When I try that new code, this happens: http://pixelbit.in/Kp4L and I get an assertion failure message? – James Anderson Nov 11 '12 at 09:14
  • Yes' that's an assertion failure message.So now you should say why you want to decode the object in that index.I wrote an alternative solution. – Ramy Al Zuhouri Nov 11 '12 at 15:34
  • If that's not what you're trying to do, please tell me what you're trying to achieve with your code. – Ramy Al Zuhouri Nov 11 '12 at 15:39