NSFileHandle&将Asynch写入iOS中的文件

时间:2012-01-13 16:39:08

标签: objective-c ios memory-management nsfilehandle

我有一种情况,我通过Web服务请求收到字节数据,并希望将其写入我的iOS设备上的文件。我曾经将所有数据(直到数据结尾)附加到内存变量中,最后使用NSStream使用stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent 将数据写入我的iOS设备中的文件:

NSFileHandle

它适用于小尺寸数据,但问题是如果我通过Web服务接收数据它可能是一大块(几个MB)并且我不想收集所有内存以将其写入文件,为了使它高效我想我必须切换到NSFileHandle几次以小块大小将数据写入同一文件。现在我的问题是这样做的最佳方法是什么?我的意思是如何使用 - (void) setUpAsynchronousContentSave:(NSData *) data { NSString *newFilePath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/MyFile.xml"]; if(![[NSFileManager defaultManager] fileExistsAtPath:newFilePath ]) { [[NSFileManager defaultManager] createFileAtPath:newFilePath contents:nil attributes:nil]; } if(!fileHandle_writer) { fileHandle_writer = [NSFileHandle fileHandleForWritingAtPath:newFilePath]; } [fileHandle_writer seekToEndOfFile]; [fileHandle_writer writeData:data]; 在BACKGROUND中写入文件?我使用这样的代码:

{{1}}

}

但是通过将1-2 Mb的数据大小传递给上述方法,我是否需要让它在后台运行?仅供参考我在主线上写作。

1 个答案:

答案 0 :(得分:8)

也许你可以试试Grand Central Dispatch

我花了一些时间尝试它,下面是我的方式。

根据Apple's document,如果我们的程序一次只需执行一个任务,我们应该创建一个“Serial Dispatch Queue”。所以,首先将队列声明为iVar。

dispatch_queue_t queue;

使用

initViewDidLoad中创建一个串行调度队列
if(!queue)
{
    queue = dispatch_queue_create("yourOwnQueueName", NULL);
}

发生数据时,请调用您的方法。

- (void) setUpAsynchronousContentSave:(NSData *) data { 

    NSString *newFilePath = [NSHomeDirectory()  stringByAppendingPathComponent:@"/Documents/MyFile.xml"];
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    if(![fileManager fileExistsAtPath:newFilePath ]) {
        [fileManager createFileAtPath:newFilePath contents:nil attributes:nil];
    }

    if(!fileHandle_writer) {
        self.fileHandle_writer = [NSFileHandle fileHandleForWritingAtPath:newFilePath];
    }
    dispatch_async( queue ,
                   ^ {
                       // execute asynchronously
                       [fileHandle_writer seekToEndOfFile];
                       [fileHandle_writer writeData:data];
                   }); 
}

最后,我们需要在ViewDidUnloaddealloc

中释放队列
if(queue)
{
    dispatch_release(queue);
}

我将这些代码与ASIHttp结合使用,并且它可以正常工作。 希望它有所帮助。