Work on locking NSFileHandle NSTask when transferring large amounts of data

I have some code that processes data from my application. It takes full XML in NSString and runs it through a PHP script to generate HTMl, RTF, etc. It works well if the user does not have a large list. This is apparently due to the fact that it overlaps the 8-pound NSPipe buffer.

I worked on this (I think) in readPipe and readHandle, but I'm not sure how to handle it in writeHandle / writePipe. The application will play baseball in [writeHandle writeData:[in..., if I do not break it in gdb, wait a few seconds, and then continue.

Any help on how I can get around this in my code?

- (NSString *)outputFromExporter:(COExporter *)exporter input:(NSString *)input {
  NSString *exportedString = nil;
  NSString *path = [exporter path];
  NSTask *task = [[NSTask alloc] init];

  NSPipe *writePipe = [NSPipe pipe];
  NSFileHandle *writeHandle = [writePipe fileHandleForWriting];
  NSPipe *readPipe = [NSPipe pipe];
  NSFileHandle *readHandle = [readPipe fileHandleForReading];

  NSMutableData *outputData = [[NSMutableData alloc] init];
  NSData *readData = nil;

  // Set the launch path and I/O for the task
  [task setLaunchPath:path];
  [task setStandardInput:writePipe];
  [task setStandardOutput:readPipe];

  // Launch the exporter, it will convert the raw OPML into HTML, Plaintext, etc
  [task launch];

  // Write the raw OPML representation to the exporter input stream
  [writeHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];
  [writeHandle closeFile];

  while ((readData = [readHandle availableData]) && [readData length]) {
    [outputData appendData:readData];
  }

  exportedString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
  return exportedString;
}
+3
6

, , , - , .

, , : . , , , . , (, ).

, UI , - , .

+1

API 10.7, NSNotifications.

task.standardOutput = [NSPipe pipe];
[[task.standardOutput fileHandleForReading] setReadabilityHandler:^(NSFileHandle *file) {
    NSData *data = [file availableData]; // this will read to EOF, so call only once
    NSLog(@"Task output! %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

    // if you're collecting the whole output of a task, you may store it on a property
    [self.taskOutput appendData:data];
}];

, task.standardError.

:

, readabilityHandler block nil; , .

[task setTerminationHandler:^(NSTask *task) {

    // do your stuff on completion

    [task.standardOutput fileHandleForReading].readabilityHandler = nil;
    [task.standardError fileHandleForReading].readabilityHandler = nil;
}];

( async), ^.

+10

NSFileHandle availableData, , :

, NSTask . NSFileHandle stdin . stdout , NSLog. , , , API NSFileHandle , , . , , . , :

data = [file readDataOfLength: 1];  // blocks infinitely

data = [file availableData]; // blocks infinitely

, . , , API NSFileHandle , , , Posix API.

, API, Qaru , , , -, AvailableData.

+4

, , , ? ?

, NSFileHandle , , , , , -subdataWithRange:, , . fileDescriptor POSIX API (fdopen, fwrite ..) . API POSIX , , .

0

, , , [writeHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];, , , .

, .

0

Take a look at asynctask.mout this meaning .

asynctask.m allows you to process more than 8 thousand input data.

0
source

Source: https://habr.com/ru/post/1717174/


All Articles