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