Огромные задержи и тормоза при разработке под iOS

И снова здравствуйте (c)

Если вам в жизни не повезло и судьба заставила вас разрабатывать приложения под мобильные дивайсы комании Apple, то этот пост будет полезен для вас.

Если вы не разработчик то лучше не читайте, это опасно!

Ато вдруг еще узнаете страшную правду что операционные системы у Яббл полное гавно, а средства разработки так вообще позапрошлый век….

В общем вернемся к тормозам и задержкам. При кодировании на ОбожеЦе (c) сплошь и рядом применяются методы с Completion Handler. Примерно 95% программистов это не пугает, потому что они тупые и считают что асинхронный метод это просто кусок кода внутри функци… Ну откуда им знать что Completion Handler исполняется через какое-то время, возможно в другом потоке, или даже на сервере!

Обычные и мелкие подтормаживания возникают из-за использования внешних данных (не инкапсулировнных) в асинхронный метод. Ну оно и понятно: надо держать ссылки, хранить копии данных между моментами создания Completion Handler и его исполнением. Самым крутым тормозом будет изменение каких-то глобальных данных из асинхронного метода, который по воле какого-то криворукого фреймворка будет исполнятся вообще в другом потоке…

Короче, если у вас под iOS что-то начало залипать на пару секунд или переодически не отрабатываются тапы и прочие действия пользователя: проверьте Комплишен Хендлеры ближайших методов, 100% там собака порылась.

Если уж так случилось (например при работе с Twitter SDK) и вам надо работать с UI (ну там окно показать, цифру в лейбе поменять, и т.д.) из асинхронного хендлера, да еще такого что вызывается 3-4 в цепочке асинхронных методов из патерна «Коллбаса» (с), и при этом не ждать секунд 30 (да-да-да именно так бывает тормозит iOS) то вот вам волшебная пиздюлина от фирмы «Надкусаное Тыблоко»:

dispatch_async(dispatch_get_main_queue(), ^{

    // Fast calling code here

});

Пример из рабочего проекта:

    //--------------------------------------------------------------------------
    // Used on Twitter API request by SLRequest object when posting is possible
    
    twitterRequestHandler = ^
    (NSData* responseData, NSHTTPURLResponse* urlResponse, NSError* error)
    {
        NSString* textOut;
        if (responseData)
        {
            NSInteger statusCode = urlResponse.statusCode;
            if (statusCode >= 200 && statusCode < 300)
            {
                textOut = @"Posting to Twitter succesfuly completed";
                NSLog(@"%@", textOut);
                megaApp->notify(event_twitter_post);
            }
            else
            {
                textOut = [NSString stringWithFormat:
                           @"Posting to Twitter ended with HTTP response: %i", statusCode];
                NSLog(@"%@", textOut);
                megaApp->notify(event_twitter_post_error);
            }
        }
        else
        {
            textOut = [NSString stringWithFormat:
                       @"Twitter.postText() failed, error: %@", error];
            megaApp->notify(event_twitter_post_error);
        }
#if DEBUG
        // Show the result as alert in debug mode
        dispatch_async(dispatch_get_main_queue(), ^{
            
            [[[UIAlertView alloc] initWithTitle       : @"Twitter"
                                  message             : textOut
                                  delegate            : nil
                                  cancelButtonTitle   : @"OK"
                                  otherButtonTitles   : nil]
             show];
            
        });
#endif
    }; // twitterRequestHandler

В общем dispatch_async() иногда помагает, но лучше старайтесь писать продуманный код, который работает полностью асинхронно и нигде ничего не лочит.

P.S. Я люблю #XCode! Я люблю #XCode! Я люблю #XCode! (с)

Автор: KARPOLAN

I am KARPOLAN https://www.patreon.com/karpolan

Огромные задержи и тормоза при разработке под iOS: 2 комментария

  1. Перейди на reactive cocoa, штука супер, колбасы с асинхронными методами не будет, там есть деливеры на какой конкретно поток тебе нужно
    Либо болты фейсбука (Bolts), но их функционал слегка ограничен.

    Переменные внутри блока менять можно используя __block id someValue;
    залазить в compleationHandler нужно, используя слабую ссылку на себя weakself. И дергать atimic property — если тебе нужна мютексная синхронизация. либо определять самому через @synchronized(self) {

    Нравится

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s

%d такие блоггеры, как: