2009-09-20 4 views
2

Я пытаюсь получить представление схемы для отображения каталога, теперь я отредактировал пример из Apple, чтобы он работал из любого установленного мной каталога, за исключением того, что при расширении любого узла я получаю «EXEC_BAD_ACCESS», из класса NSOutlineView.EXC_BAD_ACCESS при использовании NSOutlineView

Вот файл заголовка:

#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 

Update: обновленный код с последней версией

ответ

7

Вы не правильное управление памятью.

(1) Эта строка кода протекает. Autorelease экземпляр SMLDirectoryDataItem.

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

(2) В вашем -initWithPath: Родитель: метод, следующая строка кода не сохраняет строку. Пульс автореферата выпускает его при сливе. Это, скорее всего, ведущие к аварии:

relativePath = [path lastPathComponent]; 

обзор этого:

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

Есть некоторые дополнительные проблемы в коде (обновленный код):

(1) Первая и в первую очередь это ...

#define IsALeafNode ((id)-1) 

.... это полностью Неправильно. Вы передаете -1 в объекты, которые ожидают объекты. Немедленный сбой, если что-либо сохраняет/автореализовывает или иным образом передает сообщения.

(2) Кроме того, вы по-прежнему не управляете памятью правильно. Ваш -setRootDirectory: метод не сохраняет строку. Я бы предложил использовать @property и @synthesizing setter/getter.

(3) Ваш-детский метод утечки струн, как сито. В частности, использование переменной имени файла неверно.

+0

ОК, поэтому я изменил его, чтобы он не разбился, но теперь он говорит: «[__NSCFType numberOfChildren]: нераспознанный селектор отправлен в экземпляр« – kennyisaheadbanger

+0

Тогда вам придется выполнить некоторую отладку. Break on -outlineView: numberOfChildrenOfItem: и посмотреть, что такое значение и класс элемента. Затем определите, как класс предмета стал тем, чем он является. –

+0

Теперь я действительно запутался .. Я скопировал обновленный пример вещей в и теперь для метода objectValueForTableColumn делает его сбой, хотя он называется около 4 раз заранее и работает нормально ... if (item == nil) по какой-то причине не работает! – kennyisaheadbanger

Смежные вопросы