2010-12-03 64 views
5

我的應用程序允許用戶重命名當前打開的文檔。這是微不足道的,並且工作正常,有一個非常煩人的錯誤,我無法弄清楚。當文件被重命名時,AppKit(友善地)在下次嘗試保存文檔時提醒用戶。用戶說「OK」,一切正常。當應用程序外部的某些內容改變了文檔時,這是有意義的,但當文檔本身實際上完成時則不行。防止當NSDocument文件(編程)重命名時出現警告

的代碼是這樣的:

-(void)renameDocumentTo:(NSString *)newName { 
    NSURL *newURL = [[[self fileURL] URLByDeletingLastPathComponent] 
            URLByAppendingPathComponent:newName]; 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    [fileManager moveItemAtURL:[self fileURL] toURL:newURL]; 
    NSDictionary *attrs = [fileManager attributesForItemAtPath:[newURL path] error:NULL]; 

    [self setFileURL:newURL]; 
    [self setFileModificationDate:[attrs fileModificationDate]]; 
} 

有人會認爲,明確設置文檔上的新的URL和修改日期就足夠了,但遺憾的是事實並非如此。可可仍然會產生警告。

我試過改變順序(在文檔上設置新的URL,然後重命名文件),但這沒有幫助。

我也試過在CocoaDev對舊的文章在用戶提出了一個修正:

[self performSelector:@selector(_resetMoveAndRenameSensing)]; 

即使這不但是停止警告,我猜有是使用記錄的API來完成此操作的正確方法。當用戶點擊項目樹上的文件並將其重命名爲其他內容時,Xcode如何處理這些事情。它不會警告用戶有關重命名,因爲用戶實際上執行了重命名。

如果任何人都可以闡明我可能需要做的事情,那很好,謝謝!

+0

我已經開始賞金尋求幫助。不幸的是,我真的無處可去。一個簡單的測試用例就是創建一個打開一個.txt文件(或其他任何東西)的空白文檔應用程序,添加一個菜單項,其操作將打開的文件重命名爲其他內容(並使用新URL更新文檔對象)。我嘗試在重命名後第一次嘗試保存文件時規避警告。 – d11wtq 2010-12-07 11:27:19

+0

哦,如果文檔正在編輯,這需要工作。如果存在未保存的更改,則保存到磁盤,關閉文檔,移動文件然後重新打開它可能會產生不良影響。 – d11wtq 2010-12-07 11:28:41

回答

3

在主文檔中沒有太多這方面的內容。相反,看看10.5發行說明:http://developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html%23X10_5Notes標題下「NSDocument檢查修改文件在保存時間」

(在Xcode的情況下,它有很長的歷史,我不會感到驚訝,如果如果對項目中的文件不使用NSDocument

值得注意的是,移動文件不會改變其修改日期,因此調用-setFileModificationDate:不太可能產生任何效果。

這樣一個可能性是繞過NSDocument的通常的警告,像這樣:

- (void)saveDocument:(id)sender; 
{ 
    if (wasRenamed) 
    { 
     [self saveToURL:[self fileURL] ofType:[self fileType] forSaveOperation:NSSaveOperation delegate:nil didSaveSelector:nil contextInfo:NULL]; 
     wasRenamed = NO; 
    } 
    else 
    { 
     [super saveDocument:sender]; 
    } 
} 

理想情況下,你還需要檢查的可能性:

  1. 嚮應用重命名的文檔
  2. 重命名的文件然後被其他應用修改/移動
  3. 用戶前往保存文檔

那時你想要通常的警告表出現。或許可以通過類似來完成:

- (void)renameDocumentTo:(NSString *)newName 
{ 
    // Do the rename 

    [self setFileURL:newURL]; 
    wasRenamed = YES; // MUST happen after -setFileURL: 
} 

- (void)setFileURL:(NSURL *)absoluteURL; 
{ 
    if (![absoluteURL isEqual:[self fileURL]]) wasRenamed = NO; 
    [super setFileURL:absoluteURL]; 
} 

- (void)setFileModificationDate:(NSDate *)modificationDate; 
{ 
    if (![modificationDate isEqualToDate:[self fileModificationDate]]) wasRenamed = NO; 
    [super setFileModificationDate:modificationDate]; 
} 

否則,你唯一的其他選擇,我能看到的是調用的標準之一,保存了一些自定義的參數/寫方法,提示您的文檔的子類移動目前的文檔而不是實際保存它。我覺得會更棘手。也許定義你自己的NSSaveOperationType

有了這種技術,文檔系統應該明白,重命名是類似保存的操作的一部分,但需要相當多的實驗才能確定。

0

難道不可能以編程方式爲用戶回答問題嗎? 或者您可以在重命名後立即保存,這樣用戶可以一次性獲得所有答案。

我看到這個問題是啓動並運行了一段時間,所以告訴你讀reference將沒有任何好處我想..

希望我幫助一點點,雖然它不修復你的問題直接

0

很多靈感來自@邁克的回答,我得到了「移動到」的消息不再顯示通過重新路由NSSaveOperationNSSaveAsOperation。在我NSDocument子類:

  • 我超載saveDocumentWithDelegate:didSaveSelector:contextInfo:確定保存URL和文件類型(指派那些self);如果舊fileURL存在,我將其移至新位置
  • 裏面saveDocumentWithDelegate:didSaveSelector:contextInfo:我的呼叫重定向到[self saveToURL:self.fileURL ofType:self.fileType forSaveOperation:NSSaveAsOperation completionHandler: ...]而不是[super saveDocumentWithDelegate:didSaveSelector:contextInfo:]

這對我的作品。

相關問題