PropertyListFaultHandler example

From EOFWiki
Jump to: navigation, search

Contents

What we like to do

The supplied Foundation method +[NSMutableDictionary dictionaryWithContentsOfFile:pathname] doesn't load the dictionary lazily. We'd like to emploay the EOFault technology to create a lazy NSMutableDictionary class method named dictionaryByReferencingFile similiar to the NSImage method -[NSImage initByReferencingFile:].

Can we do it ?

First of all we need to check that NSMutableDictionary is large enough for an EOFault. If it isn't, than we'd need to create our own NSMutableDictionary subclass. We assume it's large enough.

We don't need an EOFault subclass

EOFault is never subclassed. All the custom logic is part of the handler. So there's nothing to do here.

We do need our own EOFaultHandler

#import <EOControl/EOControl.h>


@interface EOPropertyListFaultHandler : EOFaultHandler 
{
   id    _pathname;
}

- initByReferencingFile:(NSString *) path;

@end
#import "PropertyListFileFaultHandler.h"


@implementation PropertyListFileFaultHandler

- (id) initByReferencingFile:(NSString *) path
{
   [super init];
   
   _pathname = [path copy];
   
   return self;
}


- (void) dealloc
{
   [_pathname release];
   [super dealloc];
}


- (NSDictionary *) propertyList
{
   id                     plist;
   NSPropertyListFormat   format;
   NSString               *error;
   NSData                 *data;

   error = nil;
   data  = [NSData dataWithContentsOfFile:_pathname];
   plist = [NSPropertyListSerialization propertyListFromData:data
					    mutabilityOption:NSPropertyListImmutable 
                                                      format:&format
                                            errorDescription:&error];
   [error autorelease];
   
   return plist;
}


- (void) completeInitializationOfObject:(id) obj
{
   id   plist;
   
   plist = [self propertyList];
   
   // clearing the fault releases self (the EOFaultHandler), so keep it around some more
   [[self retain] autorelease];
   
   [EOFault clearFault:obj];
   [obj setDictionary:plist];
}

@end

Let's add a Category to make it smooth

@interface NSMutableDictionary (LazyLoading)
+ dictionaryByReferencingFile:(NSString *) path;
@end


@implementation NSMutableDictionary (LazyLoading)

- initByReferencingFile:(NSString *) path
{
   EOFaultHandler   *handler;

   self    = [self init];  // may turn placeholder into real
   handler = [[[PropertyListFileFaultHandler alloc] initByReferencingFile:path] autorelease];
   [EOFault makeObjectIntoFault:self
                    withHandler:handler];
   return self;
}


+ dictionaryByReferencingFile:(NSString *) path
{
   return [[self alloc] initByReferencingFile:path] autorelease];
}

@end

Question and Answers

Why is a NSMutableDictionary and not a NSDictionary used ?

Personal tools