Archiving strategy - comments please

  • Hi folks,

    I'm still writing my first Cocoa app and am starting on my saving and
    loading routines. I have an array of objects which are subclasses of a
    subclass of NSObject and I need to write the NSCoding protocol methods
    for these.

    In my superclass I have the method:

    - (id) initWithCoder:(NSCoder*) inCoder
    {
    if (self = [super init]) {
      [self setName:[inCoder decodeObjectForKey:@"name"]];
      [self setID:[inCoder decodeLongForKey:@"ID"]];
    }

    return(self);
    }

    (I know decodeLongForKey isn't there any more - should I use int?
    int32_t? I still have an instictive fear of int from back when you
    weren't sure of the size, and I need 32 bits for these.)

    In the subclass I will have:

    - (id) initWithCoder:(NSCoder*) inCoder
    {
    if (self = [super initWithCoder:inCoder]) {
      [self setIncome:[inCoder decodeBoolForKey:@"income"]];
      [self setIExpenditure:[inCoder decodeBoolForKey:@"expenditure"]];
    }

    return(self);
    }

    Does this all look OK? I will add containsValueForKey calls when I get
    to a production level.

    As an aside, what is a good system for storing the key names in the
    interface file? In my old (C++) system I kept an enum of single
    character identifiers but it would be nice to have meaningful labels.
    Can I set up static NSStrings?

    Thanks in advance

    Rev. Andy
  • Hi Andy,

    On Jun 14, 2005, at 5:31 AM, Andy Bettis wrote:

    > (I know decodeLongForKey isn't there any more - should I use int?
    > int32_t? I still have an instictive fear of int from back when you
    > weren't sure of the size, and I need 32 bits for these.)

    How about decodeInt32ForKey?

    > As an aside, what is a good system for storing the key names in the
    > interface file? In my old (C++) system I kept an enum of single
    > character identifiers but it would be nice to have meaningful
    > labels. Can I set up static NSStrings?

    Yes, global or file-scope NSString works well here.  You get a single
    point of definition and any possible performance overhead of creating
    the NSStrings dynamically during each pass at runtime is eliminated.

    I like to define the static NSString in the source file that "owns"
    the information:

    NSString* kMyKeyedName = @"kMyKeyedName";

    And then, if this string needs to be available to any other file,
    just define an extern reference in the owner's header or in a global
    header file (e.g. for widely shared notification or preference keys):

    extern NSString* kMyKeyedName;

    I end up doing this so much that I wrote an Xcode script to take the
    string declaration and create an extern declaration for it. I put
    this in my Xcode scripts menu and assigned a keyboard shortcut:

    #! /usr/bin/perl -w
    #
    # -- PB User Script Info --
    # %%%{PBXName=Create NSString Extern Decls}%%%
    # %%%{PBXInput=Selection}%%%
    # %%%{PBXOutput=Pasteboard}%%%
    # %%%{PBXKeyEquivalent=@8}%%%
    #
    my $outputString = "";

    my @selection = <STDIN>;      # read the selection from standard input

    if (!@selection) { return; };  # no chars in selection, nothing to do

    foreach my $line (@selection) {
            # get everything up to the "="
            my @halves = split(/ =/, $line);
            my $thisDecl = "extern " . $halves[0] . ";\n";
            $outputString .= $thisDecl;
    }

    #print "%%%{PBXSelection}%%%";
    print $outputString;
    #print "%%%{PBXSelection}%%%";