0

シンプルなファイルブラウザを構築しようとしていますが、行き詰まっています。クラスを定義し、ウィンドウを構築し、コントローラー、ビューを追加しました..すべてが機能しますが、一度だけです。NSTableView でフォルダーを再度選択するか、Folder.files からデータを取得しようとすると、メインからサイレント EXC_BAD_ACCESS (コード = 13、アドレス 0x0) が発生します。

単純なクラスで 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 サブクラスであるクラス Folder があります。

// 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]];

}

助けてください ;)

4

1 に答える 1

0

ハ!

_files = [NSArray arrayWithArray:result];

次のようにする必要があります。

_files = [[NSArray arrayWithArray:result] retain];
于 2012-12-15T11:00:04.983 に答える