2012-12-13 59 views
0

我想构建简单的文件浏览器,我卡住了。 我定义了类,构建窗口,添加控制器,视图..一切正常,但只有一次。 再次选择NSTableView中的文件夹,或尝试从Folder.files中获取数据,导致main从无提示EXC_BAD_ACCESS(code = 13,address0x0)。CoreData,瞬态属性和EXC_BAD_ACCESS。

信息有关的文件,我保持CoreData之外,在简单的类,我不想将它们保存:

#import <Foundation/Foundation.h> 

@interface TPDrawersFileInfo : NSObject 
@property (nonatomic, retain) NSString * filename; 
@property (nonatomic, retain) NSString * extension; 
@property (nonatomic, retain) NSDate * creation; 
@property (nonatomic, retain) NSDate * modified; 
@property (nonatomic, retain) NSNumber * isFile; 
@property (nonatomic, retain) NSNumber * size; 
@property (nonatomic, retain) NSNumber * label; 

+(TPDrawersFileInfo *) initWithURL: (NSURL *) url; 
@end 

@implementation TPDrawersFileInfo 
+(TPDrawersFileInfo *) initWithURL: (NSURL *) url { 
    TPDrawersFileInfo * new = [[TPDrawersFileInfo alloc] init]; 
    if (new!=nil) { 
     NSFileManager * fileManager = [NSFileManager defaultManager]; 

     NSError * error; 
     NSDictionary * infoDict = [fileManager attributesOfItemAtPath: [url path] error:&error]; 

     id labelValue = nil; 
     [url getResourceValue:&labelValue forKey:NSURLLabelNumberKey error:&error]; 
     new.label = labelValue; 

     new.size = [infoDict objectForKey: @"NSFileSize"]; 
     new.modified = [infoDict objectForKey: @"NSFileModificationDate"]; 
     new.creation = [infoDict objectForKey: @"NSFileCreationDate"]; 
     new.isFile = [NSNumber numberWithBool:[[infoDict objectForKey:@"NSFileType"] isEqualToString:@"NSFileTypeRegular"]]; 
     new.extension = [url pathExtension]; 
     new.filename = [[url lastPathComponent] stringByDeletingPathExtension]; 

    } 
    return new; 
} 

接下来,我有类文件夹,这是NSManagesObject子

// Managed Object class to keep info about folder content 

@interface Folder : NSManagedObject { 
    NSArray * _files; 
} 
@property (nonatomic, retain) NSArray * files; // Array with TPDrawersFileInfo objects 
@property (nonatomic, retain) NSString * url; // url of folder 

-(void) reload; //if url changed, load file info again. 

@end 
@implementation Folder 

@synthesize files = _files; 
@dynamic url; 

-(void)awakeFromInsert { 
    [self addObserver:self forKeyPath:@"url" options:NSKeyValueObservingOptionNew context:@"url"]; 
} 

-(void)awakeFromFetch { 
    [self addObserver:self forKeyPath:@"url" options:NSKeyValueObservingOptionNew context:@"url"]; 
} 
-(void)prepareForDeletion { 
    [self removeObserver:self forKeyPath:@"url"]; 
} 

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if (context == @"url") { 
     [self reload]; 
    } 
} 

-(void) reload { 
    NSMutableArray * result = [NSMutableArray array]; 
    NSError * error = nil; 
    NSFileManager * fileManager = [NSFileManager defaultManager]; 
    NSString * percented = [self.url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
    NSArray * listDir = [fileManager contentsOfDirectoryAtURL: [NSURL URLWithString: percented] 
            includingPropertiesForKeys: [NSArray arrayWithObject: NSURLCreationDateKey ] 
                 options:NSDirectoryEnumerationSkipsHiddenFiles 
                 error:&error]; 

    if (error!=nil) {NSLog(@"Error <%@> reading <%@> content", error, self.url);} 

    for (id fileURL in listDir) { 
     TPDrawersFileInfo * fi = [TPDrawersFileInfo initWithURL:fileURL]; 
     [result addObject: fi]; 
    } 

    _files = [NSArray arrayWithArray:result]; 

} 


@end 

在应用程序的委托我定义

@interface TPAppDelegate : NSObject <NSApplicationDelegate> { 
    IBOutlet NSArrayController * foldersController; 
    Folder * currentFolder; 
} 
- (IBAction)chooseDirectory:(id)sender; // choose folder 

- (Folder *) getFolderObjectForPath: path { 
    //gives Folder object if already exist or nil if not 
..... 
} 

- (IBAction)chooseDirectory:(id)sender { 
    //Opens panel, asking for url 
    NSOpenPanel * panel = [NSOpenPanel openPanel]; 
    [panel setCanChooseDirectories:YES]; 
    [panel setCanChooseFiles:NO]; 
    [panel setMessage:@"Choose folder to show:"]; 
    NSURL * currentDirectory; 

    if ([panel runModal] == NSOKButton) 
    { 
     currentDirectory = [[panel URLs] objectAtIndex:0]; 
    } 

    Folder * folderObject = [self getFolderObjectForPath:[currentDirectory path]]; 

    if (folderObject) { 
     //if exist: 
     currentFolder = folderObject; 
    } else { 
     // create new one 
     Folder * newFolder = [NSEntityDescription 
           insertNewObjectForEntityForName:@"Folder" 
           inManagedObjectContext:self.managedObjectContext]; 
     [newFolder setValue:[currentDirectory path] forKey:@"url"]; 
     [foldersController addObject:newFolder]; 
     currentFolder = newFolder; 
    } 
    [foldersController setSelectedObjects:[NSArray arrayWithObject:currentFolder]]; 

} 

请帮助;)

回答

0

哈!

_files = [NSArray arrayWithArray:result]; 

应该是:

_files = [[NSArray arrayWithArray:result] retain]; 
+0

考虑使用ARC! – paulmelnikow

相关问题