пʼятниця, 18 січня 2013 р.

@Objective-C (senior level) @"Retain cycle and weak references"

Нещодавно я зіштовхнувся з цим безпощадним явищем в одному з моїх проектів. Я давно знав, що ARC  це не панацея, але в моєму випадку це виявилися ліки з вкрапленнями яду. Звісно яд я туди сам підливав шляхом не досконалого стилю програмування і не знанням певних речей. Справа в тому, що як виявилося в моєму випадку, не повне розуміння ARC + не знання підводних каменів GCD, можуть "кинути" так, що поїздка на американських гірках виявляється простою дитячою забавою.
Ті хто хоч трохи програмували під мобільні технології, чудово розуміють основну проблему- проблему нестачі пам"яті. Коли за пару хвилин ти набираєш did recived memory warning, то ти з жахом розумієш, що ти створив не просто "кровосісю", а кровосісю в квадраті чи кубі. Саме страшне було те, що навіть коли скрін вигружався я з жахом дивився на показники інструментів, які показували стабільний ріст накопичуваної пам"яті. Забігаючи на перед, маю сказати, що ця "кровосіся" зводила мене з розуму  десь добу! Для себе я виніс один урок, якщо бачиш, що в тебе починається паніка, зупинись  просто попроси когось про допомогу, тому що коли ти починаєш писати хаки, то ти не вирішуєш задачу, ти просто усугубляєш і маскуєш яму в яку потім всерівно попадеш. Мені повезло, що мені трапилась людина, яка сіла, подивилась на код і сказала :- @"Zachem ty eto delaesh, ty ge sam ponemaesh chto ono ne bydet rabotaty'" і саме страшне, що він був правий, я розумів, що це дійсно наврядчи допоможе, це не лікування, а просте зализування рани. Отож, висновук був оперувати код, а не давати йому аскорбінки.
Після певного часу, я точно не можу сказати скількох годин, хвороба була розпізнана, детально про неї можна почитати тут: http://www.informit.com/articles/article.aspx?p=1856389&seqNum=5 для того щоб запірнути  глибше ось ще пару додаткових посилань для кращої ясності картини: http://dannysu.com/2012/07/30/automatic-reference-counting-on-ios/ також http://www.cocoanetics.com/2012/03/block-retain-loop/
В докі Apple http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html можна чудово побачити
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyViewController = myController;
myController.completionHandler =  ^(NSInteger result) {
    [weakMyViewController dismissViewControllerAnimated:YES completion:nil];
};

Справа в тому що в мене жила тьма місць в коді, де можна було зіштовхнуться з таким:
 dispatch_async(dispatch_get_main_queue(), ^{
        [self makeSomething];
        self.carsArray = [self generatePark];
    });

Тепер це переписано як:

MyViewController * __weak weakMyViewController = myController;

dispatch_async(dispatch_get_main_queue(), ^{
        [weakMyViewController makeSomething];
        weakMyViewController.carsArray = [weakMyViewController generatePark];
    });



І тепер ніхто нікого не тримає, всі задоволені, волосся перестає сивіти.



Немає коментарів:

Дописати коментар