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:
- Do I need to implement
encodeWithCoder:
andinitWithCoder:
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? - 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 methodinitWithFrame:
there?