NSFileHandle и запись асинхронных файлов в iOS - PullRequest
3 голосов
/ 13 января 2012

У меня возникает ситуация, когда я получаю байтовые данные через запрос веб-служб и хочу записать их в файл на моем устройстве iOS.Раньше я добавлял все данные (до конца данных) в переменную памяти и в конце записывал данные, используя NSStream, в файл на моем устройстве iOS, используя метод:

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

Это прекрасно работает длянебольшой размер данных, но проблема в том, что если я получаю данные через веб-сервисы, это может быть большой кусок (пара МБ), и я не хочу собирать все данные в памяти, чтобы записать их в файл, чтобы сделать их эффективными.Я думаю, мне нужно переключиться на 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 Мб к указанному выше методу, мне нужно, чтобы он работал в фоновом режиме?К вашему сведению, я пишу в главной теме.

1 Ответ

8 голосов
/ 13 января 2012

Может быть, вы можете попробовать Grand Central Dispatch .

Я потратил некоторое время, пытаясь это сделать, вот мой способ сделать это.

Согласно документу Apple , если нашей программе нужно выполнять только одну задачу за раз, мы должны создать «Последовательную очередь отправки». Итак, сначала объявите очередь как 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];
                   }); 
}

Наконец, нам нужно освободить очередь в ViewDidUnload или dealloc

if(queue)
{
    dispatch_release(queue);
}

Я объединяю этот код с ASIHttp, и он работает. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...