문제

디렉토리를 표시하기 위해 개요보기를 얻으려고 노력하고 있습니다. 이제 Apple에서 예제를 편집하여 NSOUTLINEVIEW 클래스에서 "EXEC_BAD_ACCESS"를 확장 할 때를 제외하고 설정 한 디렉토리에서 작동하도록했습니다.

헤더 파일은 다음과 같습니다.

#import <Cocoa/Cocoa.h>

@interface SMLDirectoryDataSource : NSObject {
    NSString *rootDirectory;
}

- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item;
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item;
- (id)outlineView:(NSOutlineView *)outlineView
            child:(int)index
           ofItem:(id)item;
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn
           byItem:(id)item;
- (void) setRootDirectory:(NSString *)directory;

@end

@interface SMLDirectoryDataItem : NSObject
{
    NSString *relativePath, *fullPath;
    SMLDirectoryDataItem *parent;
    NSMutableArray *children;
}

//+ (SMLDirectoryDataItem *)rootItem;
- (int)numberOfChildren;// Returns -1 for leaf nodes
- (SMLDirectoryDataItem *)childAtIndex:(int)n;// Invalid to call on leaf nodes
- (NSString *)fullPath;
- (NSString *)relativePath;

@end

그리고 구현 파일은 다음과 같습니다.

#import "SMLDirectoryDataSource.h"


@implementation SMLDirectoryDataSource
- (id)initWithDirectory:(NSString *)path
{
    rootDirectory = path;
    return self;
}

- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
    return (item == nil) ? 1 : [item numberOfChildren];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
    return (item == nil) ? NO : ([item numberOfChildren] != -1);
}

- (id)outlineView:(NSOutlineView *)outlineView
            child:(int)index
           ofItem:(id)item
{
    NSLog(@"hi there");
    if(rootDirectory == nil)
            rootDirectory = @"/";
    NSLog(rootDirectory);
    if(item == nil){
        SMLDirectoryDataItem *item = [[SMLDirectoryDataItem alloc] initWithPath:rootDirectory parent:NULL];
        return item;
        [item release];
    }
    else
        return [(SMLDirectoryDataItem *)item childAtIndex:index];
}
/*(
- (id)outlineView:(NSOutlineView *)outlineView
objectValueForTableColumn:(NSTableColumn *)tableColumn
           byItem:(id)item
{
    if(rootDirectory == nil)
        rootDirectory = @"/";
    return rootDirectory;
}
*/
- (void)setRootDirectory:(NSString *)directory
{
    rootDirectory = directory;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    if(item == nil)
        return rootDirectory;
    else
        return (id)[(SMLDirectoryDataItem *)item relativePath];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    return NO;
}

@end

@implementation SMLDirectoryDataItem

//static SMLDirectoryDataItem *rootItem = nil;
#define IsALeafNode ((id)-1)

- (id)initWithPath:(NSString *)path parent:(SMLDirectoryDataItem *)obj
{
    fullPath = [path copy];
    if (self = [super init])
    {
        relativePath = [[path lastPathComponent] copy];
        parent = obj;
    }
    return self;
}


/*+ (SMLDirectoryDataItem *)rootItem
{
    if (rootItem == nil) rootItem = [[SMLDirectoryDataItem alloc] initWithPath:@"/" parent:nil];
    return rootItem;
}*/


// Creates, caches, and returns the array of children
// Loads children incrementally
- (NSArray *)children
{
    if (children == NULL) {
        NSFileManager *fileManager = [NSFileManager defaultManager];
        //NSString *fullPath = [self fullPath];
        BOOL isDir, valid = [fileManager fileExistsAtPath:fullPath isDirectory:&isDir];
        if (valid && isDir) {
            NSArray *array = [fileManager contentsOfDirectoryAtPath:fullPath error:NULL];
            if (!array) {   // This is unexpected
                children = [[NSMutableArray alloc] init];
            } else {
                NSInteger cnt, numChildren = [array count];
                children = [[NSMutableArray alloc] initWithCapacity:numChildren];
                NSString *filename = [[NSString alloc] init];
                for (cnt = 0; cnt < numChildren; cnt++) {
                    filename = [fullPath stringByAppendingPathComponent:[array objectAtIndex:cnt]];
                    SMLDirectoryDataItem *item = [[SMLDirectoryDataItem alloc] initWithPath:filename parent:self];
                    [children addObject:item];
                    [item release];
                }
                [filename release];
            }
        } else {
            NSLog(@"is a leaf... strange");
            children = IsALeafNode;
        }
    }
    return children;
}


- (NSString *)relativePath
{
    return relativePath;
}


- (NSString *)fullPath
{
    // If no parent, return our own relative path
    //if (parent == nil) return relativePath;

    // recurse up the hierarchy, prepending each parent’s path
    //return [[parent fullPath] stringByAppendingPathComponent:relativePath];
    return fullPath;
}

- (SMLDirectoryDataItem *)childAtIndex:(int)n
{
    return [[self children] objectAtIndex:n];
}

- (int)numberOfChildren
{
    id tmp = [self children];
    return (tmp == IsALeafNode) ? (0) : [tmp count];
}


- (void)dealloc
{
    if (children != IsALeafNode) [children release];
    [relativePath release];
    [super dealloc];
}

@end

업데이트: 최신 버전으로 코드를 업데이트했습니다

도움이 되었습니까?

해결책

메모리를 올바르게 관리하지 않습니다.

(1)이 코드 유출 라인. SMLDirectoryDataitem 인스턴스를 자동 제출합니다.

    return (item == nil) ? [[SMLDirectoryDataItem alloc] initWithPath:rootDirectory parent:nil] : [item childAtIndex:index];

(2) -initwithpath : parent : method에서 다음 코드 줄은 문자열을 유지하지 않습니다. AutoreLease 풀은 배수되면이를 방출합니다. 이것은 당신의 충돌로 이어질 가능성이 높습니다.

    relativePath = [path lastPathComponent];

검토 :

http://developer.apple.com/mac/library/documentation/cocoa/conceptual/memorymgmt/memorymgmt.html

코드에는 몇 가지 추가 문제가 있습니다 (업데이트 된 코드).

(1) 가장 먼저, 이것은 ...

#define IsALeafNode ((id)-1)

.... 완전히 잘못되었습니다. 당신은 객체를 기대하는 것들로 -1을 전달하고 있습니다. 보유/자동 표시 또는 다른 메시지가있는 경우 즉시 충돌.

(2) 또한 여전히 메모리를 올바르게 관리하지 않습니다. -SetRootDirectory : 메소드가 문자열을 유지하지 않습니다. @property를 사용하고 @synthesize a setter/getter를 사용하는 것이 좋습니다.

(3) -자녀 방법은 체처럼 줄을 새는 것입니다. 특히 파일 이름 변수의 사용법이 잘못되었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top