2012-10-16 21 views
9

मैं अपने पैकेज दस्तावेज़ के लिए NSFileWrapper का उपयोग कर रहा हूं। कभी-कभी, जब मैं पैकेज के अंदर फ़ाइल के डेटा का अनुरोध करता हूं तो मुझे nil मिलता है।NSFileWrapper शून्य लौटाता है, कभी-कभी

यह वह जगह है मैं पैकेज के अंदर एक फ़ाइल का डेटा कैसे क्वेरी:

- (NSData*) dataOfFile(NSString*)filename { 
    NSFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename]; 
    return fileWrapper.regularFileContents; // This returns nil sometimes. Why? 
} 

इस विधि अंत में कुछ फाइलें (सभी नहीं) के लिए शून्य लौटने शुरू होता है। अफसोस की बात है, मैं लगातार समस्या को पुन: उत्पन्न करने में कामयाब नहीं रहा हूं।

- (BOOL) readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError { 
    self.documentFileWrapper = fileWrapper; 
    return YES; 
} 

यह मैं पैकेज के अंदर एक फ़ाइल के डेटा को अपडेट है:

- (void) updateFile:(NSString*)filename withData:(NSData*)data { 
    SBFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename]; 
    if (fileWrapper) { 
     [self.documentFileWrapper removeFileWrapper:fileWrapper]; 
    } 
    NSFileWrapper *fileWrapper = [[SBFileWrapper alloc] initRegularFileWithContents:data ]; 
    fileWrapper.preferredFilename = filename; 
    [self.documentFileWrapper addFileWrapper:fileWrapper]; 
} 

यह मैं कैसे को बचाने के है

मामले में यह मदद करता है में, यह मैं कैसे पैकेज को खोलने है पैकेज:

- (NSFileWrapper*) fileWrapperOfType:(NSString *)typeName error:(NSError *__autoreleasing *)outError { 
    return self.documentFileWrapper; 
} 

यह क्यों हो सकता है? क्या इसे रोकने का कोई तरीका है?

regularFileContents के प्रलेखन इस समस्या के बारे में बात करने के लिए प्रकट होता है:

This method may return nil if the user modifies the file after you call readFromURL:options:error: or initWithURL:options:error: but before NSFileWrapper has read the contents of the file. Use the NSFileWrapperReadingImmediate reading option to reduce the likelihood of that problem.

लेकिन मुझे समझ नहीं आता क्या कोड में परिवर्तित करने की ऊपर इस स्थिति को रोकने के लिए है।

विफल प्रयोगों

मैं दस्तावेज़ को सहेजने अगर regularFileContents वापसी शून्य लेकिन यह अभी भी बाद में नहीं के बराबर रिटर्न की कोशिश की। इस तरह:

- (NSData*) dataOfFile(NSString*)filename { 
    NSFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename]; 
    NSData *data = fileWrapper.regularFileContents; 
    if (!data) { 
      [self saveDocument:nil]; 
      fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename]; 
      data = fileWrapper.regularFileContents; 
    } 
    return data; 
} 
+0

यह एक पागल अनुमान है, लेकिन मुझे आश्चर्य है अगर सुर्खियों फ़ाइल को संशोधित करने के बाद आप को बचाने (यह फ़ाइल या कुछ और reindexes) की तरह जिम्मेदार बताते हैं? मैं थोड़ी उत्सुक हूं कि आप विफल होने के बाद क्यों बचत कर रहे हैं; इसके बजाए इसे दोबारा क्यों नहीं खोलें? कोशिश करने और आपको कुछ विचार देने के लिए बस अनुमान लगाया। – Dad

+0

जंगली अनुमान, लेकिन मुझे लगता है कि आपकी वस्तु जारी हो जाती है। शायद आवंटन के साथ कुछ गलत हो जाता है। क्या आपने विश्लेषण का प्रयास किया? आवंटन और init (और स्वयं। + Autorelease और रिलीज) के साथ सावधान रहें। – Roger

उत्तर

3

वास्तव में क्या चल रहा है यह देखने के लिए पर्याप्त कोड नहीं है। हालांकि मूल कारण यह है कि NSFileWrapper बस इसका नाम क्या है: एक ऑब्जेक्ट एक फ़ाइल या निर्देशिका का प्रतिनिधित्व करता है। इसलिए, वास्तविक फ़ाइल या निर्देशिका आसानी से ऑब्जेक्ट के साथ "synch से बाहर" प्राप्त कर सकती है, जो स्मृति में रहता है। जब भी NSFileWrapper निर्धारित करता है कि यह हुआ है, यह कुछ संचालन के लिए शून्य देता है। समाधान NSFileWrapper वस्तुओं को अल्पकालिक बनाने के लिए है। जब आपको उनकी आवश्यकता हो तो बनाएं और खोलें और फिर जितनी जल्दी हो सके सहेजें और बंद करें।

विशेष रूप से, ऐसा लगता है कि आपका कोड लंबे समय तक एक पैकेज निर्देशिका रैपर में पॉइंटर रख रहा है और यह मानता है कि यह हमेशा मान्य है। यदि निर्देशिका किसी भी कारण से बदलती है, तो यह मामला नहीं है। रिकोड करें ताकि आपको हर बार एक नई पैकेज निर्देशिका रैपर मिल जाए, और समस्या को दूर जाना चाहिए।

0

यदि फ़ाइल डिस्क पर बदलती है तो आपको शून्य मिलेगा (जैसा कि @ जीन कहते हैं)। हालांकि, अगर आप matchesContentsOfURL: विधि का उपयोग कर इस जाँच कर सकते हैं जो:

determines whether a disk representation may have changed, based on the file attributes stored the last time the file was read or written. If the file wrapper’s modification time or access permissions are different from those of the file on disk, this method returns YES. You can then use readFromURL:options:error:

यह Working with File Wrappers से एप्पल प्रलेखन।

उस अनुभाग से परिचय से इस नोट:

Because the purpose of a file wrapper is to represent files in memory, it’s very loosely coupled to any disk representation. A file wrapper doesn’t record the path to the disk representation of its contents. This allows you to save the same file wrapper with different URLs, but it also requires you to record those URLs if you want to update the file wrapper from disk later.

तो तुम अगर आप इसे फिर से पढ़ना चाहते/जरूरत मूल फाइल करने के लिए यूआरएल को बचाने के लिए होगा।

क्या matchesContentsofURL: रिटर्न जब आप परिणाम शून्य देख रहे हैं सुनने के लिए दिलचस्प है।