2011-12-28 61 views
2

我是新來的objective-c。我已經在Python和C++中學習過類,但是我對Objective-C真的很感興趣,所以在過去的幾天裏我一直在學習。這個程序應該比較兩個位置的文件並添加丟失的文件。一個簡單的同步,雖然目前並不是所有的功能都實現。不良訪問調用Objective-C方法

該錯誤是由recursivelyGetContentsOfDirectory函數引起的。它返回錯誤EXEC_BAD_ACCESS。由於它實際上並不在函數中,我假設它與它的定義有關。

#import <AppKit/AppKit.h> 

@interface Sync : NSControl{ 
    NSURL *baseToDirectory; 
    NSURL *baseFromDirectory; 

    NSArray *filesInBaseFromDirectory; 

    IBOutlet NSTextField *baseToDirectoryLabel; 
    IBOutlet NSTextField *baseFromDirectoryLabel; 
} 
- (IBAction)chooseBaseSyncFromDirectory:(id)sender; 
- (IBAction)chooseBaseSyncToDirectory:(id)sender; 
- (IBAction)performSync:(id)sender; 

void recursivelyGetContentsOfDirectory (NSURL *path); 

@end 

實現文件

#import "Sync.h" 

@implementation Sync 


- (IBAction)chooseBaseSyncFromDirectory:(id)sender { 

    NSOpenPanel* openDlg = [NSOpenPanel openPanel]; 
    [openDlg setCanChooseDirectories:YES]; 
    [openDlg setCanChooseFiles:NO]; 
    //Open the directory 
    if ([openDlg runModal] == NSFileHandlingPanelOKButton) { 
     NSArray *files = [openDlg URLs]; 
     NSString *fileAsString = [[files objectAtIndex:0] path]; 
     [baseFromDirectoryLabel setStringValue:fileAsString]; 
     baseFromDirectory = [files objectAtIndex:0]; 
     recursivelyGetContentsOfDirectory(baseFromDirectory); 
    } 
} 

- (IBAction)chooseBaseSyncToDirectory:(id)sender { 
    NSOpenPanel* openDlg = [NSOpenPanel openPanel]; 
    [openDlg setCanChooseDirectories:YES]; 
    [openDlg setCanChooseFiles:NO]; 

    if ([openDlg runModal] == NSFileHandlingPanelOKButton) { 
     NSArray *files = [openDlg URLs]; 
     NSString *fileAsString = [[files objectAtIndex:0] path]; 
     [baseToDirectoryLabel setStringValue:fileAsString]; 
     baseToDirectory = [files objectAtIndex:0]; 
    } 
} 

void recursivelyGetContentsOfDirectory (NSURL *path){ 
    NSFileManager *tempManager; 
    NSArray *contentsOfDirectory = [tempManager contentsOfDirectoryAtPath:[path path] error:nil]; 
    for (int i = 0; i < (int)[contentsOfDirectory count] ; i = i+1) { 
     if ([[contentsOfDirectory objectAtIndex:i] isDirectory]) { 
      NSString *next = [NSString stringWithString:[path path]]; 
      [next stringByAppendingString:[contentsOfDirectory objectAtIndex:i]]; 
      NSURL *nextPath = [NSURL URLWithString:next]; 
      recursivelyGetContentsOfDirectory(nextPath); 
     } else { 
      NSLog(@"Non-Directory Found"); 
     } 
    } 
} 

- (IBAction)performSync:(id)sender { 

} 

@end 
+0

雖然你顯然沒有看到與其他方法的問題呢,你的'chooseBaseSync ...'兩個方法,如果你不使用ARC包含bug。您將'[files objectAtIndex:0]'分配給一個實例變量,但您不擁有該對象。您需要使用保留對象的setter或手動保留它。 – Chuck 2011-12-28 22:07:27

回答

2
NSFileManager *tempManager; 

你是不是創造了tempManager

它應該像

NSFileManager *tempManager=[[NSFileManager alloc] init]; 

,如果你不使用ARC,你是負責(自動)釋放tempManager。

或使用NSFileManager *tempManager = [NSFileManager defaultManager]

+0

程序中還存在一些問題,但它現在沒有任何致命錯誤。謝謝。我沒有意識到構造函數沒有被自動調用。我想我明白爲什麼。 – dbaker90 2011-12-28 21:31:44

+0

Objective-C沒有構造函數。 NSObject的方法alloc返回一個實例,而'init ...'初始化它。這是Cocoa特有的,但不是語言功能。 – vikingosegundo 2011-12-28 21:40:52

+1

@ dbaker90:在這種情況下,構造函數也不會在C++中自動調用。注意,'NSFileManager * tempManager'聲明瞭一個*指針*給一個NSFileManager對象。如果這是一個C++類,你必須做'NSFileManager * tempManager = new NSFileManager()'。這大致相當於你可以用Cocoa處理的[[[NSFileManager alloc] init]'舞蹈。不同的是,在C++中,您可以聲明兩個實際對象(其中* do *具有其默認構造函數)以及指向對象的指針,而Objective-C中的對象始終通過指針訪問。 – Chuck 2011-12-28 21:59:33