В настоящее время я работаю над приложением Cocoa, которое работает с PDF-файлами, и я использую PDFKit от Apple для выполнения этой работы. Сохранение PDF-файла является проблемой, так как я хочу показать индикатор выполнения, пока это происходит, что кажется невозможным с использованием стандартного метода writeToURL:
. Итак, я пошел и использовал Grand Central Dispatch вместо этого.PDFDocument dataRepresentation медленный ... Как показать прогресс?
Проблема в том, что метод dataRepresentation
, используемый для получения NSData для записи, очень медленный в преобразовании любого PDF-файла, большего чем ~ 3 МБ в NSData, и поэтому индикатор выполнения останавливается на несколько секунд, пока моя программа ждет данные, которые, похоже, заставляют пользователей думать, что программа полностью застопорилась. И я не хочу, чтобы они думали об этом.
Мой вопрос: есть ли что-нибудь, что я могу сделать, чтобы ускорить метод dataRepresentation
или сообщить о его прогрессе для пользователя?
Вот код Grand Central Dispatch я в конечном итоге написание:
NSData *pdf = [doc dataRepresentation]; // R-e-a-l-l-y S-l-o-w
dispatch_queue_t queue = dispatch_get_current_queue();
dispatch_data_t dat = dispatch_data_create([pdf bytes], [pdf length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
__block dispatch_io_t channel =
dispatch_io_create_with_path(DISPATCH_IO_STREAM,
[path UTF8String], // Convert to C-string
O_WRONLY, // Open for writing
0, // No extra flags
queue,
^(int error){
// Cleanup code for normal channel operation.
// Assumes that dispatch_io_close was called elsewhere.
if (error == 0) {
dispatch_release(channel);
channel = NULL;
}
});
// The next two lines make sure that the block in dispatch_io_write
// gets called about 60 times, so that it can update the progress bar.
dispatch_io_set_low_water(channel,[pdf length]/60);
dispatch_io_set_high_water(channel,[pdf length]/60);
dispatch_io_write(channel,
0,
dat,
queue,
^(bool done, dispatch_data_t data, int error) {
if (data) {
// Increment progress bar
}
if (error) {
// Handle errors
}
if (done) {
dispatch_io_close(channel, NULL);
}
});
dispatch_release(dat);
dispatch_release(queue);
Должен был подумать о поиске уведомления ... Спасибо! –