Является ли запуск вложенного NSScanner наиболее эффективным методом анализа строки повторяющихся элементов или сканирование можно выполнить за один проход?
У меня есть строка, которая возвращается из вызова командной строки (NSTAsk
) в Apple Compressor (разрывы строк отсутствуют, разрывы сделаны исключительно для простоты разборчивости этого вопроса без прокрутки):
<jobStatus name="compressor.motn" submissionTime="12/4/10 3:56:16 PM"
sentBy="localuser" jobType="Compressor" priority="HighPriority"
timeElapsed="32 second(s)" timeRemaining="0" timeElapsedSeconds="32"
timeRemainingSeconds="0" percentComplete="100" resumePercentComplete="100"
status="Successful" jobid="CD4046D8-CDC1-4F2D-B9A8-460DF6AF184E"
batchid="0C9041F5-A499-4D00-A26A-D7508EAF3F85" /jobStatus>
Они повторяются в одной и той же строке, поэтому в возвращаемой строке может быть от нуля до n:
<jobstatus .... /jobstatus><jobstatus .... /jobstatus>
<jobstatus .... /jobstatus>
Кроме того, могут быть включены другие теги, которые не имеют значения для моего кода (batchstatus в этом примере):
<jobstatus .... /jobstatus><batchstatus .... /batchstatus>
<jobstatus .... /jobstatus>
Это НЕ XML-документ, который возвращается, а просто серия блоков статуса, которые оказались завернуты в XML-подобный тег. Ни один из блоков не является вложенным. Все они носят последовательный характер. Я не контролирую возвращаемые данные.
Моя цель (и в настоящее время работающий код) разбирает строку на «задания», которые содержат словари деталей в блоке jobstatus. Любые другие блоки (например, пакетный статус) и любые другие строки игнорируются. Меня интересует только содержимое блоков jobstatus.
NSScanner * jobScanner = [NSScanner scannerWithString:dataAsString];
NSScanner * detailScanner = nil;
NSMutableDictionary * jobDictionary = [NSMutableDictionary dictionary];
NSMutableArray * jobsArray = [NSMutableArray array];
NSString * key = @"";
NSString * value = @"";
NSString * jobStatus = @"";
NSCharacterSet * whitespace = [NSCharacterSet whitespaceCharacterSet];
while ([jobScanner isAtEnd] == NO) {
if ([jobScanner scanUpToString:@"<jobstatus " intoString:NULL] &&
[jobScanner scanUpToCharactersFromSet:whitespace intoString:NULL] &&
[jobScanner scanUpToString:@" /jobstatus>" intoString:&jobStatus]) {
detailScanner = [NSScanner scannerWithString:jobStatus];
[jobDictionary removeAllObjects];
while ([detailScanner isAtEnd] == NO) {
if ([detailScanner scanUpToString:@"=" intoString:&key] &&
[detailScanner scanString:@"=\"" intoString:NULL] &&
[detailScanner scanUpToString:@"\"" intoString:&value] &&
[detailScanner scanString:@"\"" intoString:NULL]) {
[jobDictionary setObject:value forKey:key];
//NSLog(@"Key:(%@) Value:(%@)", key, value);
}
}
[jobsArray addObject:
[NSDictionary dictionaryWithDictionary:jobDictionary]];
}
}
NSLog(@"Jobs Dictionary:%@", jobsArray);
Приведенный выше код создает следующий вывод журнала:
Jobs Dictionary:(
{
batchid = "0C9041F5-A499-4D00-A26A-D7508EAF3F85";
jobType = Compressor;
jobid = "CD4046D8-CDC1-4F2D-B9A8-460DF6AF184E";
name = "compressor.motn";
percentComplete = 100;
priority = HighPriority;
resumePercentComplete = 100;
sentBy = localuser;
status = Successful;
submissionTime = "12/4/10 3:56:16 PM";
timeElapsed = "32 second(s)";
timeElapsedSeconds = 32;
timeRemaining = 0;
timeRemainingSeconds = 0;
}
Вот забота. В моем коде я просматриваю строку, а затем, когда я получаю блок данных, просматриваю эту часть, чтобы создать словарь, который заполняет массив. Это фактически означает, что строка проходится дважды. Поскольку это происходит каждые 15–30 секунд или около того и может содержать сотни заданий, я вижу в этом потенциальную нагрузку на ЦП и память, а приложение, выполняющее это, может находиться на том же компьютере, что и приложение Compressor (которое уже потребляет память и процессор) - я не хочу добавлять какую-либо нагрузку, если мне это не нужно.
Есть ли лучший способ использовать NSScanner для получения данных?
Любые советы или рекомендации очень ценятся!