2009-08-30 11 views
5

ファイルが存在するかどうかを確認する前にwriteToFileを使用してplistファイルに書き込もうとしています。ファイルが存在するかどうかを確認中にエラーが発生しました

これはコードです:

#import "WindowController.h" 

@implementation WindowController 

@synthesize contacts; 

NSString *filePath; 
NSFileManager *fileManager; 

- (IBAction)addContactAction:(id)sender { 

    NSDictionary *dict =[NSDictionary dictionaryWithObjectsAndKeys: 
         [txtFirstName stringValue], @"firstName", 
         [txtLastName stringValue], @"lastName", 
         [txtPhoneNumber stringValue], @"phoneNumber", 
         nil]; 

    [arrayContacts addObject:dict]; 

    [self updateFile]; 
} 

- (void)awakeFromNib { 
    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    filePath = [rootPath stringByAppendingPathComponent:@"Contacts.plist"]; 
    fileManager = [NSFileManager defaultManager]; 

    contacts = [[NSMutableArray alloc] init]; 

    if ([fileManager fileExistsAtPath:filePath]) { 

     NSMutableArray *contactsFile = [[NSMutableArray alloc] initWithContentsOfFile:filePath]; 
     for (id contact in contactsFile) { 
      [arrayContacts addObject:contact]; 
     } 
    } 
} 

- (void) updateFile { 
    if (![fileManager fileExistsAtPath:filePath] || [fileManager isWritableFileAtPath:filePath]) { 
     [[arrayContacts arrangedObjects] writeToFile:filePath atomically:YES]; 
    } 
} 

@end 

addContactActionが、私はエラーを取得しない実行が、プログラムが停止し、それがデバッガに私をもたらしているとき。私は、デバッガで継続押すと私が取得:

Program received signal: “EXC_BAD_ACCESS”. 

しかし、それはおそらく重要ではありません。

PS:私はMacプログラミングの初心者です。何がうまくいかないのかを伝えるエラーメッセージが表示されないので、何を試してみるべきか分かりません。

ファイルへのパスは次のとおりです。

/Users/andre/Documents/Contacts.plist

私は以前(同じ結果で)これを試してみましたが、私はあなたができることを読みます唯一のドキュメントフォルダへの書き込み:

/Users/andre/Desktop/NN/NSTableView/build/Debug/NSTableView.app/Contents/Resources/Contacts.plist

これが起こる理由は誰にも分かりませんが、説明がありますか?

答えて

2

filePathをstringByAppendingPathComponent:メソッドで設定しています。このメソッドは、自動解放されたオブジェクトを返します。

私が思う

(自動解放オブジェクトは、それが(自動的に)悪いアクセスエラーを引き起こす可能性があり、解放された。後に使用される)

[[rootPath stringByAppendingPathComponent:@"Contacts.plist"] retain]; 

[rootPath stringByAppendingPathComponent:@"Contacts.plist"]; 

を変更すると、あなたの悩みを解決します。

+0

うわー、本当に、私の問題を修正しました、ありがとう!問題の内容をもう少し教えてください。私は公式のリファレンスからこの行をコピーしたと確信しています。どうもありがとう! –

+0

このチュートリアルをご覧ください:http://cocoadevcentral.com/d/learn_objectivec/ 「このチュートリアルでは、現在の関数の最後に自動オブジェクトがなくなると想定できます」という行があります。 (自動オブジェクトは自動解放されたオブジェクトです)。awakeFromNib関数の後に設定した文字列が「消える」ので、filePath変数はもはや存在しないものを参照し、エラーを引き起こします。それを保持することでオートレリースされるのを止めることはありませんが、あなたがそれを伝えるまで解放されない余分なコピーが作成されます。 (あなたはおそらく-deallocでやるべきです) –

+0

AndréHoffmann:Appleはよく隠されていますが、ADCウェブサイトのCocoaメモリ管理に関する非常に良いチュートリアルを持っています。 http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html –

7

まず、NSFileManagerオブジェクトをインスタンス化しないでください。これでプログラムがデバッガに破壊されている行に指定することができ、その後

[[NSFileManager defaultManager] fileExistsAtPath: filePath]; 

:代わりに、あなたはこのようなデフォルトのファイルマネージャを使用しますか?

+0

どこの回線が壊れているのが見えますか?アセンブリコードのみを表示します。 fileManager..hovedインスタンス化のヒントをありがとうが、事を変更していない。 –

+0

Cocoaコード内でクラッシュすると、アセンブリのみが表示されます。デバッガウィンドウの左側にスタックフレームのリストがあります。自分のコードにあるものを選択すると、ソースコードが表示され、該当する行が赤で強調表示されます。 –

+0

ピーターありがとう。 –

関連する問題