0

I wrapped NSRects in NSValues to get them into an NSMutableArray. I now want to add saving/loading capabilities to my app, so I thought I'd use NSKeyedArchiver and NSKeyedUnarchiver. Wrong! NSKeyedArchiver cannot archive structs. After a bit of searching I found a forum post from someone with the same problem. He solved it by using NSArchiver and NSUnarchiver. I implemented that, but once again, it didn't work. I can now encode it, but if I decode my array, I get back an array of NSRects! You can't even put them into an array! But I don't care, as long as I can get my rects back. But I can't, because NSArray only has methods for retrieving an object. A struct is not an object, so I can't retrieve my rects. How is this possible? How can I retrieve my archived rects?

Part of MyDocument.m:

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
    NSMutableArray *array = odview.ovals;
    return [NSArchiver archivedDataWithRootObject:array];
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
    NSMutableArray *array = [NSUnarchiver unarchiveObjectWithData:data];
    NSMutableArray *newOvals = [NSMutableArray array];
    NSLog(@"array: %@", array);
    NSUInteger i, count = [array count];
    for (i = 0; i < count; i++) {
        NSRect rect = [array objectAtIndex:i];            // I can't do that because a struct is not an object!
        [newOvals addObject:[NSValue valueWithRect:rect]];
    }
    odview.ovals = newOvals;
    return YES  ;
}

How is is possible the wrapping NSValues disappear and how can I safely save and load my NSRects?

11684
  • 7,356
  • 12
  • 48
  • 71
  • 1
    It is not possible -- NSRects are not objects, so they cannot possibly appear in an NSArray. What makes you think this is happening? –  Jan 30 '13 at 17:29
  • The NSLog statement. I'd be the first one to agree with you this is impossible. if it wasn't for the output of the `NSLog` statement: `2013-01-30 17:47:38.440 OvalFun[1000:a0f] array: ( "NSRect: {{207, 82}, {150, 207}}", "NSRect: {{87, 79}, {218, 133}}" )` – 11684 Jan 30 '13 at 17:31
  • 2
    What does the debugger say? I doubt these are NSRects, they are probably NSValues and the -description; method is giving you the report you're seeing. NSArray's -description method cannot print an NSRect, it would crash. – iluvcapra Jan 30 '13 at 17:38

1 Answers1

0

I think the easiest way is to use NSStringFromCGRect and CGRectFromString to convert back and forth -- store the rects as strings in your array and then just use writeToFile:atomically: (or writeToURL:atomically:) to save your array.

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • Is it performance heavy to convert these strings to rects every frame (for drawing my view)? – 11684 Jan 30 '13 at 17:33
  • @11684, I don't think it would be any "heavier" than converting from an NSValue. – rdelmar Jan 30 '13 at 17:35
  • Oh, haha! These are actually NSRects, so I am using NSStringFromRect and NSRectFromString. Any difference? – 11684 Jan 30 '13 at 17:38
  • @11684, oh right, sorry I missed that. The output you're getting from your log looks like the description method is using NSStringFromRect to convert the values into something useful to look at. – rdelmar Jan 30 '13 at 17:41
  • Aha. Now there is something strange: although the array is set to correctly formatted strings and I can convert them to NSRects, nothing is drawn from the loaded array (I _did_ `[self setNeedsDisplay:YES];`)... Any ideas? – 11684 Jan 30 '13 at 17:43
  • @11684, not without seeing your code. Besides, that's another question. If my response answered your question, you should accept it, and post another question (with code) to ask about this other problem. – rdelmar Jan 30 '13 at 17:46
  • Yeah, you're right... Thanks! I'll take a closer look at my setter for `ovals` then. – 11684 Jan 30 '13 at 17:47