mirror of
https://github.com/gnustep/apps-gorm.git
synced 2025-04-22 22:20:44 +00:00
Crash prevention.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/gorm/trunk@19447 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2258535535
commit
bf62865daa
3 changed files with 254 additions and 234 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2004-06-03 00:43 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* Gorm.m: Removed code in the testInterface: method to allow
|
||||
NSBrowser, NSTableView, and NSOutlineView display correctly in
|
||||
testing mode.
|
||||
* GormDocument.m: Moved the code in loadDocument: into a NS_DURING
|
||||
block to catch any exceptions thrown during loading of a .gorm file.
|
||||
This will facilitate recovery of the application when a problem is
|
||||
encountered while loading the file and will allow the user to continue
|
||||
using the application despite the issue.
|
||||
|
||||
2004-05-30 22:37 Gregory John Casamento <greg_casamento@yahoo.com>
|
||||
|
||||
* GormDocument.m: [GormFirstResponder connectInspectorClassName]
|
||||
|
|
5
Gorm.m
5
Gorm.m
|
@ -693,12 +693,14 @@ NSString *GormResizeCellNotification = @"GormResizeCellNotification";
|
|||
intoClassName: @"NSPopUpButton"];
|
||||
[archiver encodeClassName: @"GormNSPopUpButtonCell"
|
||||
intoClassName: @"NSPopUpButtonCell"];
|
||||
/*
|
||||
[archiver encodeClassName: @"GormNSBrowser"
|
||||
intoClassName: @"NSBrowser"];
|
||||
[archiver encodeClassName: @"GormNSTableView"
|
||||
intoClassName: @"NSTableView"];
|
||||
[archiver encodeClassName: @"GormNSOutlineView"
|
||||
intoClassName: @"NSOutlineView"];
|
||||
*/
|
||||
[archiver encodeRootObject: activDoc];
|
||||
data = RETAIN([archiver archiverData]); // Released below...
|
||||
[activDoc endArchiving];
|
||||
|
@ -1188,8 +1190,6 @@ NSString *GormResizeCellNotification = @"GormResizeCellNotification";
|
|||
return palettesManager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (id<IBSelectionOwners>) selectionOwner
|
||||
{
|
||||
return (id<IBSelectionOwners>)selectionOwner;
|
||||
|
@ -1231,7 +1231,6 @@ NSString *GormResizeCellNotification = @"GormResizeCellNotification";
|
|||
isConnecting = NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) validateMenuItem: (NSMenuItem*)item
|
||||
{
|
||||
GormDocument *active = (GormDocument*)[self activeDocument];
|
||||
|
|
472
GormDocument.m
472
GormDocument.m
|
@ -1766,263 +1766,273 @@ static NSImage *classesImage = nil;
|
|||
*/
|
||||
- (id) loadDocument: (NSString*)aFile
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
NSMutableDictionary *nt;
|
||||
NSMutableDictionary *cc;
|
||||
NSData *data;
|
||||
NSUnarchiver *u;
|
||||
GSNibContainer *c;
|
||||
NSEnumerator *enumerator;
|
||||
id <IBConnectors> con;
|
||||
NSString *ownerClass, *key;
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
BOOL isDir = NO;
|
||||
NSDirectoryEnumerator *dirEnumerator;
|
||||
BOOL repairFile = [[NSUserDefaults standardUserDefaults] boolForKey: @"GormRepairFileOnLoad"];
|
||||
|
||||
if ([mgr fileExistsAtPath: aFile isDirectory: &isDir])
|
||||
NS_DURING
|
||||
{
|
||||
// if the data is in a directory, then load from objects.gorm
|
||||
if (isDir == NO)
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
NSMutableDictionary *nt;
|
||||
NSMutableDictionary *cc;
|
||||
NSData *data;
|
||||
NSUnarchiver *u;
|
||||
GSNibContainer *c;
|
||||
NSEnumerator *enumerator;
|
||||
id <IBConnectors> con;
|
||||
NSString *ownerClass, *key;
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
BOOL isDir = NO;
|
||||
NSDirectoryEnumerator *dirEnumerator;
|
||||
BOOL repairFile = [[NSUserDefaults standardUserDefaults] boolForKey: @"GormRepairFileOnLoad"];
|
||||
|
||||
if ([mgr fileExistsAtPath: aFile isDirectory: &isDir])
|
||||
{
|
||||
NSString *lastComponent = [aFile lastPathComponent];
|
||||
NSString *parent = [aFile stringByDeletingLastPathComponent];
|
||||
NSString *parentExt = [parent pathExtension];
|
||||
|
||||
// test if we're doing it wrong...
|
||||
if([lastComponent isEqual: @"objects.gorm"] &&
|
||||
[parentExt isEqual: @"gorm"])
|
||||
// if the data is in a directory, then load from objects.gorm
|
||||
if (isDir == NO)
|
||||
{
|
||||
NSRunAlertPanel(NULL,
|
||||
_(@"Cannot load directly from objects.gorm file, please load from the gorm package."),
|
||||
@"OK", NULL, NULL);
|
||||
return nil;
|
||||
NSString *lastComponent = [aFile lastPathComponent];
|
||||
NSString *parent = [aFile stringByDeletingLastPathComponent];
|
||||
NSString *parentExt = [parent pathExtension];
|
||||
|
||||
// test if we're doing it wrong...
|
||||
if([lastComponent isEqual: @"objects.gorm"] &&
|
||||
[parentExt isEqual: @"gorm"])
|
||||
{
|
||||
NSRunAlertPanel(NULL,
|
||||
_(@"Cannot load directly from objects.gorm file, please load from the gorm package."),
|
||||
@"OK", NULL, NULL);
|
||||
return nil;
|
||||
}
|
||||
|
||||
data = [NSData dataWithContentsOfFile: aFile];
|
||||
NSDebugLog(@"Loaded data from file...");
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *newFileName;
|
||||
|
||||
newFileName = [aFile stringByAppendingPathComponent: @"objects.gorm"];
|
||||
data = [NSData dataWithContentsOfFile: newFileName];
|
||||
NSDebugLog(@"Loaded data from %@...", newFileName);
|
||||
}
|
||||
|
||||
data = [NSData dataWithContentsOfFile: aFile];
|
||||
NSDebugLog(@"Loaded data from file...");
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *newFileName;
|
||||
|
||||
newFileName = [aFile stringByAppendingPathComponent: @"objects.gorm"];
|
||||
data = [NSData dataWithContentsOfFile: newFileName];
|
||||
NSDebugLog(@"Loaded data from %@...", newFileName);
|
||||
// no file exists...
|
||||
data = nil;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no file exists...
|
||||
data = nil;
|
||||
}
|
||||
|
||||
// check the data...
|
||||
if (data == nil)
|
||||
{
|
||||
NSRunAlertPanel(NULL,
|
||||
[NSString stringWithFormat: @"Could not read '%@' data", aFile],
|
||||
@"OK", NULL, NULL);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an unarchiver, and use it to unarchive the nib file while
|
||||
* handling class replacement so that standard objects understood
|
||||
* by the gui library are converted to their Gorm internal equivalents.
|
||||
*/
|
||||
u = [[NSUnarchiver alloc] initForReadingWithData: data];
|
||||
|
||||
// classes
|
||||
[u decodeClassName: @"GSNibContainer"
|
||||
asClassName: @"GormDocument"];
|
||||
[u decodeClassName: @"GSNibItem"
|
||||
asClassName: @"GormObjectProxy"];
|
||||
[u decodeClassName: @"GSCustomView"
|
||||
asClassName: @"GormCustomView"];
|
||||
[u decodeClassName: @"NSMenu"
|
||||
asClassName: @"GormNSMenu"];
|
||||
[u decodeClassName: @"NSWindow"
|
||||
asClassName: @"GormNSWindow"];
|
||||
[u decodeClassName: @"NSPanel"
|
||||
asClassName: @"GormNSPanel"];
|
||||
[u decodeClassName: @"NSPopUpButton"
|
||||
asClassName: @"GormNSPopUpButton"];
|
||||
[u decodeClassName: @"NSPopUpButtonCell"
|
||||
asClassName: @"GormNSPopUpButtonCell"];
|
||||
[u decodeClassName: @"NSBrowser"
|
||||
asClassName: @"GormNSBrowser"];
|
||||
[u decodeClassName: @"NSTableView"
|
||||
asClassName: @"GormNSTableView"];
|
||||
[u decodeClassName: @"NSOutlineView"
|
||||
asClassName: @"GormNSOutlineView"];
|
||||
|
||||
c = [u decodeObject];
|
||||
if (c == nil || [c isKindOfClass: [GSNibContainer class]] == NO)
|
||||
{
|
||||
NSRunAlertPanel(NULL, _(@"Could not unarchive document data"),
|
||||
_(@"OK"), NULL, NULL);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// retrieve the custom class data...
|
||||
cc = [[c nameTable] objectForKey: GSCustomClassMap];
|
||||
if (cc == nil)
|
||||
{
|
||||
cc = [NSMutableDictionary dictionary]; // create an empty one.
|
||||
[[c nameTable] setObject: cc forKey: GSCustomClassMap];
|
||||
}
|
||||
[classManager setCustomClassMap: cc];
|
||||
NSDebugLog(@"cc = %@", cc);
|
||||
NSDebugLog(@"customClasses = %@", [classManager customClassMap]);
|
||||
|
||||
// convert from old file format...
|
||||
if (isDir == NO)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [aFile stringByDeletingPathExtension];
|
||||
s = [s stringByAppendingPathExtension: @"classes"];
|
||||
if (![classManager loadCustomClasses: s])
|
||||
|
||||
// check the data...
|
||||
if (data == nil)
|
||||
{
|
||||
NSRunAlertPanel(NULL, _(@"Could not open the associated classes file.\n"
|
||||
@"You won't be able to edit connections on custom classes"),
|
||||
_(@"OK"), NULL, NULL);
|
||||
NSRunAlertPanel(NULL,
|
||||
[NSString stringWithFormat: @"Could not read '%@' data", aFile],
|
||||
@"OK", NULL, NULL);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [aFile stringByAppendingPathComponent: @"data.classes"];
|
||||
if (![classManager loadCustomClasses: s])
|
||||
|
||||
/*
|
||||
* Create an unarchiver, and use it to unarchive the nib file while
|
||||
* handling class replacement so that standard objects understood
|
||||
* by the gui library are converted to their Gorm internal equivalents.
|
||||
*/
|
||||
u = [[NSUnarchiver alloc] initForReadingWithData: data];
|
||||
|
||||
// classes
|
||||
[u decodeClassName: @"GSNibContainer"
|
||||
asClassName: @"GormDocument"];
|
||||
[u decodeClassName: @"GSNibItem"
|
||||
asClassName: @"GormObjectProxy"];
|
||||
[u decodeClassName: @"GSCustomView"
|
||||
asClassName: @"GormCustomView"];
|
||||
[u decodeClassName: @"NSMenu"
|
||||
asClassName: @"GormNSMenu"];
|
||||
[u decodeClassName: @"NSWindow"
|
||||
asClassName: @"GormNSWindow"];
|
||||
[u decodeClassName: @"NSPanel"
|
||||
asClassName: @"GormNSPanel"];
|
||||
[u decodeClassName: @"NSPopUpButton"
|
||||
asClassName: @"GormNSPopUpButton"];
|
||||
[u decodeClassName: @"NSPopUpButtonCell"
|
||||
asClassName: @"GormNSPopUpButtonCell"];
|
||||
[u decodeClassName: @"NSBrowser"
|
||||
asClassName: @"GormNSBrowser"];
|
||||
[u decodeClassName: @"NSTableView"
|
||||
asClassName: @"GormNSTableView"];
|
||||
[u decodeClassName: @"NSOutlineView"
|
||||
asClassName: @"GormNSOutlineView"];
|
||||
|
||||
c = [u decodeObject];
|
||||
if (c == nil || [c isKindOfClass: [GSNibContainer class]] == NO)
|
||||
{
|
||||
NSRunAlertPanel(NULL, _(@"Could not open the associated classes file.\n"
|
||||
@"You won't be able to edit connections on custom classes"),
|
||||
NSRunAlertPanel(NULL, _(@"Could not unarchive document data"),
|
||||
_(@"OK"), NULL, NULL);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
[classesView reloadData];
|
||||
|
||||
/*
|
||||
* In the newly loaded nib container, we change all the connectors
|
||||
* to hold the objects rather than their names (using our own dummy
|
||||
* object as the 'NSOwner'.
|
||||
*/
|
||||
ownerClass = [[c nameTable] objectForKey: @"NSOwner"];
|
||||
if (ownerClass)
|
||||
[filesOwner setClassName: ownerClass];
|
||||
[[c nameTable] setObject: filesOwner forKey: @"NSOwner"];
|
||||
[[c nameTable] setObject: firstResponder forKey: @"NSFirst"];
|
||||
|
||||
/* Iterate over the contents of nameTable and create the connections */
|
||||
nt = [c nameTable];
|
||||
enumerator = [[c connections] objectEnumerator];
|
||||
while ((con = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSString *name;
|
||||
id obj;
|
||||
|
||||
name = (NSString*)[con source];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setSource: obj];
|
||||
name = (NSString*)[con destination];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setDestination: obj];
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we merge the objects from the nib container into our own data
|
||||
* structures, taking care not to overwrite our NSOwner and NSFirst.
|
||||
*/
|
||||
[nt removeObjectForKey: @"NSOwner"];
|
||||
[nt removeObjectForKey: @"NSFirst"];
|
||||
[connections addObjectsFromArray: [c connections]];
|
||||
[nameTable addEntriesFromDictionary: nt];
|
||||
[self rebuildObjToNameMapping];
|
||||
|
||||
// repair the .gorm file, if needed.
|
||||
if(repairFile == YES)
|
||||
{
|
||||
[self _repairFile];
|
||||
}
|
||||
|
||||
/*
|
||||
* set our new file name
|
||||
*/
|
||||
ASSIGN(documentPath, aFile);
|
||||
[window setTitleWithRepresentedFilename: documentPath];
|
||||
|
||||
/*
|
||||
* read in all of the sounds in the .gorm wrapper and
|
||||
* load them into the editor.
|
||||
*/
|
||||
dirEnumerator = [mgr enumeratorAtPath: documentPath];
|
||||
if (dirEnumerator)
|
||||
{
|
||||
NSString *file = nil;
|
||||
NSArray *fileTypes = [NSSound soundUnfilteredFileTypes];
|
||||
while ((file = [dirEnumerator nextObject]))
|
||||
|
||||
// retrieve the custom class data...
|
||||
cc = [[c nameTable] objectForKey: GSCustomClassMap];
|
||||
if (cc == nil)
|
||||
{
|
||||
if ([fileTypes containsObject: [file pathExtension]])
|
||||
cc = [NSMutableDictionary dictionary]; // create an empty one.
|
||||
[[c nameTable] setObject: cc forKey: GSCustomClassMap];
|
||||
}
|
||||
[classManager setCustomClassMap: cc];
|
||||
NSDebugLog(@"cc = %@", cc);
|
||||
NSDebugLog(@"customClasses = %@", [classManager customClassMap]);
|
||||
|
||||
// convert from old file format...
|
||||
if (isDir == NO)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [aFile stringByDeletingPathExtension];
|
||||
s = [s stringByAppendingPathExtension: @"classes"];
|
||||
if (![classManager loadCustomClasses: s])
|
||||
{
|
||||
NSString *soundPath;
|
||||
|
||||
NSDebugLog(@"Add the sound %@", file);
|
||||
soundPath = [documentPath stringByAppendingPathComponent: file];
|
||||
[soundsView addObject: [self _createSoundPlaceHolder: soundPath]];
|
||||
NSRunAlertPanel(NULL, _(@"Could not open the associated classes file.\n"
|
||||
@"You won't be able to edit connections on custom classes"),
|
||||
_(@"OK"), NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* read in all of the images in the .gorm wrapper and
|
||||
* load them into the editor.
|
||||
*/
|
||||
dirEnumerator = [mgr enumeratorAtPath: documentPath];
|
||||
if (dirEnumerator)
|
||||
{
|
||||
NSString *file = nil;
|
||||
NSArray *fileTypes = [NSImage imageFileTypes];
|
||||
while ((file = [dirEnumerator nextObject]))
|
||||
else
|
||||
{
|
||||
if ([fileTypes containsObject: [file pathExtension]])
|
||||
NSString *s;
|
||||
|
||||
s = [aFile stringByAppendingPathComponent: @"data.classes"];
|
||||
if (![classManager loadCustomClasses: s])
|
||||
{
|
||||
NSString *imagePath;
|
||||
id placeHolder;
|
||||
|
||||
imagePath = [documentPath stringByAppendingPathComponent: file];
|
||||
placeHolder = [self _createImagePlaceHolder: imagePath];
|
||||
if (placeHolder)
|
||||
NSRunAlertPanel(NULL, _(@"Could not open the associated classes file.\n"
|
||||
@"You won't be able to edit connections on custom classes"),
|
||||
_(@"OK"), NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
[classesView reloadData];
|
||||
|
||||
/*
|
||||
* In the newly loaded nib container, we change all the connectors
|
||||
* to hold the objects rather than their names (using our own dummy
|
||||
* object as the 'NSOwner'.
|
||||
*/
|
||||
ownerClass = [[c nameTable] objectForKey: @"NSOwner"];
|
||||
if (ownerClass)
|
||||
[filesOwner setClassName: ownerClass];
|
||||
[[c nameTable] setObject: filesOwner forKey: @"NSOwner"];
|
||||
[[c nameTable] setObject: firstResponder forKey: @"NSFirst"];
|
||||
|
||||
/* Iterate over the contents of nameTable and create the connections */
|
||||
nt = [c nameTable];
|
||||
enumerator = [[c connections] objectEnumerator];
|
||||
while ((con = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSString *name;
|
||||
id obj;
|
||||
|
||||
name = (NSString*)[con source];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setSource: obj];
|
||||
name = (NSString*)[con destination];
|
||||
obj = [nt objectForKey: name];
|
||||
[con setDestination: obj];
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we merge the objects from the nib container into our own data
|
||||
* structures, taking care not to overwrite our NSOwner and NSFirst.
|
||||
*/
|
||||
[nt removeObjectForKey: @"NSOwner"];
|
||||
[nt removeObjectForKey: @"NSFirst"];
|
||||
[connections addObjectsFromArray: [c connections]];
|
||||
[nameTable addEntriesFromDictionary: nt];
|
||||
[self rebuildObjToNameMapping];
|
||||
|
||||
// repair the .gorm file, if needed.
|
||||
if(repairFile == YES)
|
||||
{
|
||||
[self _repairFile];
|
||||
}
|
||||
|
||||
/*
|
||||
* set our new file name
|
||||
*/
|
||||
ASSIGN(documentPath, aFile);
|
||||
[window setTitleWithRepresentedFilename: documentPath];
|
||||
|
||||
/*
|
||||
* read in all of the sounds in the .gorm wrapper and
|
||||
* load them into the editor.
|
||||
*/
|
||||
dirEnumerator = [mgr enumeratorAtPath: documentPath];
|
||||
if (dirEnumerator)
|
||||
{
|
||||
NSString *file = nil;
|
||||
NSArray *fileTypes = [NSSound soundUnfilteredFileTypes];
|
||||
while ((file = [dirEnumerator nextObject]))
|
||||
{
|
||||
if ([fileTypes containsObject: [file pathExtension]])
|
||||
{
|
||||
NSDebugLog(@"Add the image %@", file);
|
||||
[imagesView addObject: placeHolder];
|
||||
NSString *soundPath;
|
||||
|
||||
NSDebugLog(@"Add the sound %@", file);
|
||||
soundPath = [documentPath stringByAppendingPathComponent: file];
|
||||
[soundsView addObject: [self _createSoundPlaceHolder: soundPath]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSDebugLog(@"nameTable = %@",[c nameTable]);
|
||||
|
||||
// awaken all elements after the load is completed.
|
||||
enumerator = [[c nameTable] keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
id o = [[c nameTable] objectForKey: key];
|
||||
if ([o respondsToSelector: @selector(awakeFromDocument:)])
|
||||
|
||||
/*
|
||||
* read in all of the images in the .gorm wrapper and
|
||||
* load them into the editor.
|
||||
*/
|
||||
dirEnumerator = [mgr enumeratorAtPath: documentPath];
|
||||
if (dirEnumerator)
|
||||
{
|
||||
[o awakeFromDocument: self];
|
||||
}
|
||||
NSString *file = nil;
|
||||
NSArray *fileTypes = [NSImage imageFileTypes];
|
||||
while ((file = [dirEnumerator nextObject]))
|
||||
{
|
||||
if ([fileTypes containsObject: [file pathExtension]])
|
||||
{
|
||||
NSString *imagePath;
|
||||
id placeHolder;
|
||||
|
||||
imagePath = [documentPath stringByAppendingPathComponent: file];
|
||||
placeHolder = [self _createImagePlaceHolder: imagePath];
|
||||
if (placeHolder)
|
||||
{
|
||||
NSDebugLog(@"Add the image %@", file);
|
||||
[imagesView addObject: placeHolder];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSDebugLog(@"nameTable = %@",[c nameTable]);
|
||||
|
||||
// awaken all elements after the load is completed.
|
||||
enumerator = [[c nameTable] keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil)
|
||||
{
|
||||
id o = [[c nameTable] objectForKey: key];
|
||||
if ([o respondsToSelector: @selector(awakeFromDocument:)])
|
||||
{
|
||||
[o awakeFromDocument: self];
|
||||
}
|
||||
}
|
||||
|
||||
// this is the last thing we should do...
|
||||
[nc postNotificationName: IBDidOpenDocumentNotification
|
||||
object: self];
|
||||
|
||||
// release the unarchiver.. now that we're all done...
|
||||
RELEASE(u);
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSRunAlertPanel(NULL, [NSString stringWithFormat: @"Failed to load file. Exception: %@",[localException reason]],
|
||||
_(@"OK"), NULL, NULL);
|
||||
return nil; // This will cause the calling method to release the document.
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
||||
// this is the last thing we should do...
|
||||
[nc postNotificationName: IBDidOpenDocumentNotification
|
||||
object: self];
|
||||
|
||||
// release the unarchiver.. now that we're all done...
|
||||
RELEASE(u);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue