4

To give some context, I'm new to iOS/Objective-C with a web dev (Ruby/JS/C#) background. I understand how the classes work, but I don't understand why the original implementors wrote these two classes (NSKeyedArchiver and NSKeyedUnarchiver) instead of consolidating both encoding and decoding logic into a single class.

Reading the Apple documentation for the abstract class NSCoder a NSCoder has methods to both encode and decode. The only thing I can think of is that the code was long so the original implementer split it into 2... It seems to me that it'd be more convenient to the developer that only a single class is used, but maybe I'm missing something nuanced about this. So are there any historical reasons for this? Was NSCoder a "convenience" in that it defines both the encoding/decoding APIs, but meant to be separated into encoder/decoders? Am I misunderstanding what a NSCoder is supposed to do?

John K. Chow
  • 1,651
  • 16
  • 24

1 Answers1

3

I think that keeping archiving and unarchiving functionality in separate classes is the result of applying the Single Responsibility Principle, which says that a class has to have a single, narrow, responsibility, which should be fully encapsulated inside that class. Indeed, when you create an instance of NSCoder's subclass, you do that either to archive a group of objects, or to unarchive data into a group of objects, but not both.

This design is not ideal, because now you have several pairs of classes (i.e. NSArchiver/NSUnarchiver and NSKeyedArchiver/NSKeyedUnarchiver) linked by communicational cohesion, while a single-class design would have lead to this data dependency being fully encapsulated. This is a tradeoff on which the designers of the Cocoa library could have gone either way. It appears that they picked single responsibility principle, at the price of introducing a data format dependency.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    Might be true, then again Apple created NSPortCoder which does actually implement both encoding as well as decoding functionality. If I understand Apple's documentation correctly, the encoding and decoding methods have sometimes been split into different classes for performance reasons (see last 2 paragraphs): https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/Archiving/Articles/subclassing.html#//apple_ref/doc/uid/20000951 – Wolfgang Schreurs Dec 05 '13 at 16:09
  • @WolfgangSchreurs That's the point I was trying to make - that there is no ideal design decision to this problem, so Cocoa designers were bound to take one or the other. Thanks! – Sergey Kalinichenko Dec 05 '13 at 16:15
  • Thanks @dasblinkenlight for the answer, appreciated the conceptual references :) But I'm still a bit confused with NSCoder then, since it seems to be violating the SRP by having methods for both encoding/decoding (both NSArchiver and NSUnarchiver inherit from it). Why not have two separate abstract classes, NSEncoder and NSDecoder? It just seems weird to me that the NSArchiver has decode methods to it... But then again, I'm still an ObjC noob :) – John K. Chow Dec 05 '13 at 17:57
  • 1
    @JohnK.Chow Since `NSCoder` is an abstract class, one could argue that it has no responsibility at all, because it is closer to interfaces than to classes. On the other hand, I think the designers could have gone either way on this, as they did - see `NSPortCoder` (for the most part, deprecated) which implements the entire interface defined by `NSCoder`. – Sergey Kalinichenko Dec 05 '13 at 18:17
  • Good points. Final question (and I apologize if this is nooby): so are there a lot of examples like NSCoder where it acts as a consolidated interface for its subclasses, or is this a unique case in Cocoa world? – John K. Chow Dec 05 '13 at 20:02
  • @JohnK.Chow I cannot think of other examples similar to this one off the top of my head. However, my familiarity with Cocoa framework is somewhat limited (I have never developed in Objective-C commercially), so I may very well be wrong on this one. – Sergey Kalinichenko Dec 05 '13 at 20:09
  • @WolfgangSchreurs any thoughts on this? – John K. Chow Dec 06 '13 at 02:44
  • 2
    @John: keep in mind that Objective-C is a pretty ancient language, as is the Foundation API. Perhaps when the Foundation API was initially developed at NeXT it seemed like a good idea to combine both encoding and decoding in 1 class. I agree it would have been cleaner to separate these responsibilities in 2 different base classes. – Wolfgang Schreurs Dec 06 '13 at 03:04