mikeash.com pyblog/friday-qa-2010-08-12-implementing-nscoding.html commentshttp://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsmikeash.com Recent CommentsThu, 28 Mar 2024 18:55:53 GMTPyRSS2Gen-1.0.0http://blogs.law.harvard.edu/tech/rssmikeash - 2010-08-16 03:05:27http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsGood point on possibly overwriting instance variables. I suppose if you use <code>[self init]</code> or similar, you shouldn't be replacing instance variables directly. <br /> <br />For implementing <code>NSCoding</code>, I think the best approach is to decode the values you need, then call through to the "real" initializer. <br /> <br />Incidentally, I think <code>NSView</code>'s approach of having two separate designated initializers is painful and really shouldn't have been built that way. If <code>initWithCoder:</code> would call through to <code>initWithFrame:</code>, it would avoid a decent bit of hassle involved in subclassing Cocoa views. Too late to change it now, I imagine. <br /> <br />While it works to have multiple designated initializers (so long as only one ever runs), I think it's best to try to only ever have one.baf46ccdfce03217dfb5c7d156f9a957Mon, 16 Aug 2010 03:05:27 GMTKen Ferry - 2010-08-16 02:28:24http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsThe call to [self init] from -initWithCoder: could probably use some more discussion - I would have written [super init] there. <br /> <br />Done as you have here, -initWithCoder: is not a designated initializer of the class. -initWithCoder: is a designated initializer of say, NSView, so this is a pitfall. If the -init method of this class or any subclass writes to any of the ivars, code in -initWithCoder: method of this class or one of its subclasses is likely to overwrite the ivars and leak. <br /> <br />I thought you had a post on designated initializers, but maybe not. In any case, the goal is to make this rule true: One and only one of each class's designated initializes runs during the bringup of an object. Each _class_, not object, has a set of designated initializers. The sets of designated initializers of a class and of its superclass are not necessarily related. d2b9e449011067103b81cafb2ba00575Mon, 16 Aug 2010 02:28:24 GMTYT - 2010-08-14 16:14:55http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsThank you for your answer! As always, it's a great article.0ae6cfcd20d972e7cb0ee77ce5f859f5Sat, 14 Aug 2010 16:14:55 GMTmikeash - 2010-08-14 15:34:32http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsWell, <code>int</code> is 32-bit even on 64-bit Mac OS X, so the only problem there is endianness. <code>NSCoder</code> knows about endianness and will take care of any byte flipping. <br /> <br />For a type of inconsistent size, such as <code>NSInteger</code>, it will also take care of adjusting the size. However, if you use such a size, you must ensure that you never store a value on the 64-bit machine that can't be represented on the 32-bit machine, otherwise you'll get an exception when decoding.827e0838ec86518a65f36e785137cf81Sat, 14 Aug 2010 15:34:32 GMTYT - 2010-08-14 06:02:18http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsWhat happens if you encodeInt:forKey: on a 64 bit ppc machine, and then decodeInt:forKey: the resulting archive on a 32 bit intel machine, say? 85d11d84f576765b24b09809870d3477Sat, 14 Aug 2010 06:02:18 GMTjt - 2010-08-14 01:32:57http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsThanks once again, Mike, for taking the time to bring us another terrific instalment.d832ac108502551f803df94929ecfc9cSat, 14 Aug 2010 01:32:57 GMTmikeash - 2010-08-13 22:57:26http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsI'd really wonder at any code that had to serialize and deserialize a view controller. Typically you should only be serializing model objects. (Nibs are obviously a big exception to this, but of course that's already done for you.) What was your use case for this? <br /> <br />Anyway, that's the sort of advice which isn't completely universal, but by the time you need to violate it you'll know enough to do so, so it isn't necessary to spell out all of the caveats.ec366998fb5e6462d7a4da807a08efa8Fri, 13 Aug 2010 22:57:26 GMTFarcaller - 2010-08-13 20:49:18http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#comments&gt; You must call the superclass versions if the superclass implements NSCoding <br /> <br />Actually no. A sample is iOS'es UIViewContoller that implements its view serialization as a part of encodeWithCoder:. I had a case when I need to serialize the UIViewController subclass that creates its view in runtime, so I had to override encodeWithCoder: with own version that does not call the superclass. This way it would be deserealized with view==nil and could re-create the view according to new UI conditions.ddc23a7af58deeb9da689c34812ee357Fri, 13 Aug 2010 20:49:18 GMTPeter - 2010-08-13 18:55:41http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsJust a heads-up: I've noticed that specifying a different name for a class causes a crash in iOS 3.2.6644ce8eab5a19017462c2a0d897993eFri, 13 Aug 2010 18:55:41 GMTmikeash - 2010-08-13 17:14:44http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsYou must call the superclass versions if the superclass implements <code>NSCoding</code>, but not if it doesn't. That's the case if you subclass <code>NSObject</code>, but also any one of the numerous other classes that don't implement it.ec0cd5c9600f854f802d6a70a87c2f8eFri, 13 Aug 2010 17:14:44 GMTJose Vazquez - 2010-08-13 17:05:07http://www.mikeash.com/?page=pyblog/friday-qa-2010-08-12-implementing-nscoding.html#commentsThanks for the post. This article would have saved me some headaches a few weeks ago. <br /> <br />I do have one more related question. From what I understood in the Hillegass book, you should call encodeWithEncoder: and initWithEncoder: on super if you are subclassing something other than NSObject. You didn't mention that in your article, so I wonder if you disagree or simply forgot to mention it. <br /> <br />Thanks again for the article. e1bad8d6af8b1719259159cdce3680a3Fri, 13 Aug 2010 17:05:07 GMT