2013-07-29 4 views
3

Надеюсь, это даже возможно.Как сделать UIProgressView, чтобы показать прогресс загрузки NSArray из файла (iPhone)?

У меня есть код для загрузки очень большой файл (словарь) после начала приложения:

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    NSString *filePath = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] 
     pathForResource:@"en_US" ofType:@"txt"] 
     encoding:NSUTF8StringEncoding error:nil]; 
    dictionary = [NSSet setWithArray:[NSArray arrayWithArray: 
     [filePath componentsSeparatedByCharactersInSet: 
     [NSCharacterSet whitespaceAndNewlineCharacterSet]]]]; 
} 

Также у меня есть правильный код в viewDidLoad:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.progressView.progress = 0.0; 
    [self performSelectorOnMainThread: 
     @selector(applicationDidFinishLaunching:) 
     withObject:nil 
     waitUntilDone:NO]; 
} 

Но у меня есть не знаю, как заставить UIProgressView показать ход создания NSSetdictionary от NSArray. Это займет несколько секунд в iOS Simulator, поэтому на устройстве он может взять более дюжины. Мне действительно нужно показать прогресс, и я предпочитаю этот путь, нежели Activity Indicator View.

Меня интересует, как получить количество импортированных товаров в данный момент (количество всех предметов известно).

Любая идея? :)

+0

Знаете ли вы, какая часть занимает больше времени, чем вам хотелось бы? Чтение файла или создание словаря? –

+0

Я не уверен, что ваш выше код читается из файла. Вместо этого он, похоже, формирует набор из массива, образованного компонентами пути к файлу. Ни в коем случае он не читает фактические байты файла. Я что-то пропустил? –

+0

@MikeD первый. Построение словаря из массива почти не заметно. –

ответ

0

Использование SVProgressHUD. У него есть делегаты, такие как showProgress, чтобы показать прогресс.

EDIT:

Обратите внимание, что это всего лишь предположение о подходе, а не практическая реализация. В зависимости от вашего наблюдения вы можете или не можете его реализовать.

Если это локальный файл, вы можете получить некоторое расчетное предположение об общем времени, которое требуется для чтения всего файла. Затем разделите это время на 100.

Создайте асинхронную очередь для чтения из файла, используя один из arrayWithContentsOfFile или dictionaryWithContentsOfFile или что-то еще. Внедряйте таймер на основной поток и увеличивайте прогресс на 1 через него и продолжайте прокладывать прогресс в основном потоке (не читайте прогресс от асинхронного потока, потому что он никогда не расскажет вам об этом, мы его подделываем).

После arrayWithContentsOfFile возвращается, сообщение 100% на основной теме. Возможно, вам потребуется немного настроить, чтобы быть точным (например, в Windows, где вы постоянно наблюдаете, как время загрузки файла меняется), но вариация не будет такой, как я полагаю. Каждый тип целевого устройства предоставил аппаратное обеспечение и память, поэтому это будет просто функция размера файла.

+1

Это не очень помогает, так как суть вопроса заключается в том, чтобы показать прогресс, основанный на количестве прочитанных байтов, а не на том, какой вид использовать. –

0

Если у вас есть длинный текстовый файл для синтаксического анализа, классы framework займут много времени. Вы не можете это изменить. И вы не можете изменить то, что они никогда не перезвонят во время работы, чтобы рассказать вам о своем прогрессе.

Ваш единственный шанс - выполнить разделение текстового файла самостоятельно и установить свой прогресс, когда вы копаете себя через свой текстовый файл. Вы можете разделить текстовый файл на регулярные выражения. «\ W +» собирают слова с хотя бы одним символом.

Если вы установили индикатор выполнения в режиме тяжелой работы, вы должны дать ему некоторое время для обновления экрана один раз в то время. См. «Магия футурита» ниже.

Возможно, в качестве отправной точки может выступать следующее - в коде ниже содержимое текстового файла хранится в «содержании» NSString.

NSError *error = NULL; 
NSRegularExpression *regex = [NSRegularExpression 
           regularExpressionWithPattern:@"\\w+" 
           options:NSRegularExpressionCaseInsensitive 
           error:&error]; 

[regex enumerateMatchesInString:content 
         options:0 
          range:NSMakeRange(0, [content length]) 
        usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){ 
         // push one match to the dictionary 
         [dictionary addObject:[content substringWithRange:match.range]]; 

         // update the progress bar 
         NSDate* futureDate = [NSDate dateWithTimeInterval:0.001 sinceDate:[NSDate date]]; 
         [[NSRunLoop currentRunLoop] runUntilDate:futureDate]; 
         self.progressbar.progress = (float) match.range.location/content.length; 
}]; 

Обратите внимание, что код не оптимизирован для скорости.Например, вы не должны обновлять индикатор выполнения с каждый токен. В зависимости от того, сколько токенов у вас есть - подсчитайте обнаруженные и обновите панель pgogress каждые 100 совпадений или так ...

+0

Я не уверен, что ваш solutinon имеет смысл. Вы указали, что существует 'NSString * content' с уже загруженным текстовым файлом, но это не так. И для создания требуется время, которое я хотел бы показать с индикатором выполнения. –

+0

OK. Как «большой» - ваш текстовый файл? Шахта загружает 4 МБ в splitsecond на устройстве. Но фактический синтаксический анализ занимает 90% времени. – DerWOK

+0

У вас была такая же стартовая ситуация: 'NSString * filePath = [NSString stringWithContentsOfFile'. Поэтому я считаю, что показ прогресса важен не при загрузке. Попробуйте решение. Если также загрузка занимает много времени, посмотрите на чтение с потоками, как выяснено [здесь] (http://stackoverflow.com/questions/1044334/objective-c-reading-a-file-line-by-line?answertab=votes # закладок сверху). Удачи! – DerWOK

0

Чтобы запустить асинхронный запрос для получения данных словаря, вам необходимо использовать NSURLRequest/NSURLConnection. Делегаты NSURLConnection дадут вам оставшиеся байты и оставшиеся байты, где вы можете выполнить асинхронную отправку в основной поток, чтобы обновить значение представления прогресса.

+0

Мой словарь хранится локально, поэтому мне не нужно его загружать. Просто хочу показать ход загрузки в память. –

+0

Хорошо, я неправильно понял ваш вопрос. – DrBug