Синтаксис та семантика вже добре визначені іншими відмінними відповідями на це питання. Оскільки виконання та виконання детально не детально, я додам свою відповідь.
Яка функціональна різниця між цими 3?
Я завжди вважав атомний за замовчуванням досить цікавим. На рівні абстракції, над яким ми працюємо, використання атомних властивостей для класу як транспортного засобу для досягнення 100% безпеки ниток - це кутовий випадок. Для справді правильних багатопотокових програм втручання програміста майже напевно є вимогою. Тим часом характеристики продуктивності та виконання ще не були детально деталізовані. Написавши кілька сильно багатопотокових програм протягом багатьох років, я декларував свої властивості як nonatomic
цілий час, оскільки атомний не був чутливим для будь-яких цілей. Під час обговорення деталей атомних та неатомних властивостей цього питання , я зробив деяке профілювання, зіткнувшись з цікавими результатами.
Виконання
Добре. Перше, що я хотів би прояснити, - це те, що реалізація блокування є визначеною та абстрагованою реалізацією. Луї використовує @synchronized(self)
у своєму прикладі - я бачив це як загальне джерело плутанини. Реалізація не на самому ділі використовувати @synchronized(self)
; він використовує блокування віджимань на об'єктному рівні . Ілюстрація Луї добре підходить для ілюстрацій високого рівня за допомогою конструктів, які ми всі знайомі, але важливо знати, що вона не використовується @synchronized(self)
.
Ще одна відмінність полягає в тому, що атомні властивості зберігатимуть / звільнятимуть цикл ваших об'єктів всередині геттера.
Продуктивність
Ось цікава частина: Продуктивність за допомогою доступу до атомних властивостей у безспорних (наприклад, однониткових) випадках може бути дуже швидкою у деяких випадках. У менш ніж ідеальних випадках використання атомних доступів може коштувати більше ніж у 20 разів більше, ніж їх витрати nonatomic
. У той час як оскаржений випадок із використанням 7 потоків був у 44 рази повільнішим для трибайтової структури (2,2 ГГц Core i7 Quad Core, x86_64). Трибайтова структура - приклад властивості дуже повільної.
Цікава сторона: приналежні користувачеві трибайтові структури були в 52 рази швидшими, ніж синтезовані атомні аксесуари; або 84% швидкість синтезованих неатомічних аксесуарів.
Об'єкти в оскаржуваних справах також можуть перевищувати 50 разів.
Зважаючи на кількість оптимізацій та варіацій в реалізації, досить важко виміряти реальні наслідки в цих контекстах. Ви часто можете почути щось на кшталт "Довіряйте, якщо ви не переглянете і не виявите, що це проблема". Через рівень абстракції вимірювати фактичний вплив насправді досить важко. Відстеження фактичних витрат з профілів може зайняти дуже багато часу, а через абстракції - зовсім неточно. Крім того, ARC проти MRC може змінити велику роль.
Тож давайте відступимо, не зосереджуючись на здійсненні доступу до власності, ми включимо звичайних підозрюваних, як-от objc_msgSend
, і вивчимо деякі реальні результати високого рівня для багатьох дзвінків до NSString
геттера у беззаперечних випадках (значення в секундах):
- MRC | неатомічні | вручну реалізовані геттери: 2
- MRC | неатомічні | синтезований геттер: 7
- MRC | атомний | синтезований геттер: 47
- АРК | неатомічні | синтезований геттер: 38 (примітка: ARC додає тут кількість відліку циклу)
- АРК | атомний | синтезований геттер: 47
Як ви, напевно, здогадувались, активність / циклічний перелік еталонів є важливим фактором для атомів та під ARC. Ви також побачите більші відмінності в оскаржуваних справах.
Хоча я приділяю пильну увагу продуктивності, я все ж кажу Семантика Перша! . Тим часом ефективність роботи є низьким пріоритетом для багатьох проектів. Однак, знання деталей виконання та витрат технологій, які ви використовуєте, безумовно, не зашкодить. Ви повинні використовувати правильну технологію для своїх потреб, цілей та можливостей. Сподіваємось, це допоможе вам заощадити кілька годин порівнянь та допоможе прийняти більш обґрунтоване рішення при розробці програм.