0

I am working on challenges from iOS Big Nerd Ranch book of 12th chapter and there is a problem of saving an array of items to the disk. I have BNRDrawView UIView that has an array finishedLines that holds items BNRLine defined by me. I want to use NSCoder for the purpose. So, I implemented inside BNRDrawView two methods:

- (void) encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:_finishedLines forKey:finishedLinesKey];
}

- (id)initWithCoder:(NSCoder *)decoder {

self = [super initWithCoder:decoder];

if (self) {
    _finishedLines = [decoder decodeObjectForKey:finishedLinesKey];
}
    return self;
}

and trying to save finishedLines array whenever it is changed like this:

[NSKeyedArchiver archiveRootObject:self.finishedLines
                            toFile:self.finishedLinesPath];

Loading I am trying to do inside initWithFrame BNRDrawView method:

- (instancetype)initWithFrame:(CGRect)r
{
...
self.finishedLinesPath = @"/Users/nikitavlasenko/Desktop/XCodeProjects/MyFirstApp/TouchTracker/savedLines/finishedLines";
    BOOL fileExists = [[NSFileManager defaultManager]
                       fileExistsAtPath:self.finishedLinesPath];
    if (fileExists) {
        self.finishedLines = [NSKeyedUnarchiver
                              unarchiveObjectWithFile:self.finishedLinesPath];
    }
...

It gives me the error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BNRLine encodeWithCoder:]: unrecognized selector sent to instance 0x7fbd32510c40'

From here I have two questions:

  1. Do I need to implement encodeWithCoder: and initWithCoder: for ALL of the classes - let's suppose that I have a plenty of different ones, defined by me - that are inside my array that I am trying to save?
  2. If you look above to my initWithCoder: method, you can see that I need to call [super initWithCoder:decoder], but do I also need to call BNRDrawView's initializer method initWithFrame: there?

1 Answer 1

2
  1. Yes, you need to implement NSCoder in all objects that are stored inside the array.

  2. No, you don't need to call initWithFrame - initWithCoder is sufficient.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.