3

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

stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent

它适用于小数据,但问题是如果我通过 Web 服务接收数据,它可能是一大块(几 MB),我不想收集所有内存以将其写入文件,让它高效我想我必须切换到NSFileHandle多次将小块大小的数据写入同一个文件。现在我的问题是最好的方法是什么?我的意思是如何使用 写入背景中的文件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];

}

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

4

1 回答 1

8

也许你可以试试Grand Central Dispatch

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

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

dispatch_queue_t queue;

init在或ViewDidLoad使用中创建串行调度队列

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];
                   }); 
}

最后,我们需要在ViewDidUnloador中释放队列dealloc

if(queue)
{
    dispatch_release(queue);
}

我将这些代码与 ASIHttp 结合起来,它可以工作。希望能帮助到你。

于 2012-01-13T17:14:05.140 回答