Obj-C, не удалось запустить вовремя, выполняя некоторую обработку БД, которая занимает 20 секунд, совет? - PullRequest
2 голосов
/ 20 февраля 2012
Application Specific Information:
com.my-app failed to launch in time

Elapsed total CPU time (seconds): 20.090 (user 20.090, system 0.000), 100% CPU 
Elapsed application CPU time (seconds): 17.598, 87% CPU

Я внес изменение в свое приложение, и в результате теперь я запускаю функцию из applicationDidFinishLaunching, которая будет выполнять некоторую обработку базы данных.

Я в основном создаю несколько новых записей и обновляю некоторыесуществующие.

Для одного из моих существующих бета-тестеров / реальных клиентов это занимает 20 секунд.

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

Обычно этот процесс вообще не занимал бы много времени, так как обрабатывалось бы всего несколько транзакций.

Я не уверен, какпродолжить, какие-либо предложения?

Ответы [ 2 ]

2 голосов
/ 20 февраля 2012

Я предлагаю вам сделать вашу обработку БД в фоновом режиме. Возможно, вы можете отключить интерфейс или отобразить индикатор ожидания, пока вы обновляете базу данных в фоновом потоке. После этого вы можете включить интерфейс или скрыть индикатор.

Существуют разные способы создания фонового потока.

  • Создать тему вручную, используя NSThread class
  • Использование NSOperation и NSOperationQueue классов
  • Использование Grand Central Dispatch (GCD)

Надеюсь, это поможет.

Редактировать

Здесь простой код для вашей цели (после предложения @JeremyP).

Сначала создайте NSOperation подкласс

// .h
@interface YourOperation : NSOperation
{   

}

//.m
@implementation YourOperation

// override main, note that init is executed in the same thread where you alloc-init this instance
- (void)main
{    
    // sorround the thread with a pool
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // do your stuff here..

    // you could send a notification when you have finished to import your db,
    // the notification is sent in a background thread,
    // so in the place where you listen it, if you need to update the interface,
    // you need to do it in the main thread (e.g. performSelectorOnMainThread)
    [[NSNotificationCenter defaultCenter] postNotificationName:kImportComplete object:self];

    [pool drain];
    pool = nil;
}

Затем, например, в вашем делегате приложения вызовите [self import];, который можно определить следующим образом:

if (!(self.operationQueue)) {

    NSOperationQueue* q = [[NSOperationQueue alloc] init];
    [q setMaxConcurrentOperationCount:1];

    self.operationQueue = q;    
    [q release];

    YourOperation *op = [[YourOperation alloc] init];

    [self.operationQueue addOperation:op];
    [op release], op = nil;
}
0 голосов
/ 20 февраля 2012

Я бы (и раньше уже в нескольких приложениях) выполнял обновление БД в фоновом потоке и показывал пользователю экран «Пожалуйста, подождите», пока обновления завершаются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...