Як замінити слабкі посилання під час використання ARC та націлювання на iOS 4.0?


87

Я розпочав розробку свого першого додатка для iOS із Xcode 4.2 і націлювався на iOS 5.0 із шаблоном "утиліта" (той, що поставляється з FlipsideViewController).

Я прочитав, що оскільки ARC є функцією часу компіляції, вона також повинна бути сумісною з iOS 4, тому я спробував націлити свою програму на 4.3 та спробувати скомпілювати її. Коли я це роблю, я отримую таку помилку:

FlipsideViewController.m: помилка: Проблема автоматичного підрахунку посилань: Поточна ціль розгортання не підтримує автоматизовані __слабкі посилання

Він посилається на цей рядок:

@synthesize delegate = _delegate;

Ця змінна оголошується як:

@property (weak, nonatomic) IBOutlet id <FlipsideViewControllerDelegate> delegate;

Я розумію, що "слабкі посилання" не підтримуються в iOS 4, але я насправді не розумію, чому для початку я хотів би використовувати слабке посилання, і я не можу зрозуміти, як би я переписував речі, щоб уникнути його використання, поки все ще користуючись перевагами ARC (зрештою, це має працювати з iOS 4 І 5, так?)

Відповіді:


149

Для націлювання на стару ОС ви можете використовувати unsafe_unretainedзамість цього weakу своїй декларації про властивості, і вона в основному повинна працювати однаково. weakпосилання нульові, коли їх ціль відходить, але unsafe_unretainedзалишає відкритою можливість того, що об'єкт, на який ви посилаєтесь, може перетворитися на звисаючий вказівник при його виведенні. Останнє є такою ж поведінкою, як якщо б ви використовували assignяк декларацію властивостей при ручному керуванні пам'яттю.

Ви робите це, щоб уникнути циклів збереження, про що я згадав у своїй відповіді тут . Ви не хочете мати сильний вказівник на щось, що може мати сильний вказівник на вихідний об’єкт. Тоді нічого не вийде належним чином.


Дякую за пораду. Ви кажете "націлити на стару ОС ...". Чи означає це, що я повинен використовувати лише unsafe_unretain у збірках програми старше 5,0? Або я можу просто використовувати unsafe_unretain у своєму коді та побудувати його для націлювання як на 4.x, так і на 5.x?
Mason G. Zhwiti

1
@Mason - unsafe_unretainedпідтримується як в iOS 4.x, так і в 5.0, тому надає зворотну сумісність. Якщо ви виконували збірку лише на 5.0, ви можете перейти на, weakщоб скористатися додатковою безпекою, яку вона вам надає.
Бред Ларсон

Я спробував unsafe_unretain, це все одно спрацювало. Однак я отримав багато попереджень, таких як "" ** __NSAutoreleaseNoPool (): Об'єкт 0x564bd90 класу __NSArrayM автоматично випущений без пулу на місці - просто тече "*", це нормально?
п’яте

1
@fifth - Це абсолютно не пов’язана проблема. Ви запускаєте щось у фоновому потоці, не маючи на місці пулу автовипуску. Створені вручну потоки не мають власного пулу автовипуску, тому вам потрібно створити його самостійно, використовуючи @autoreleasepool(під ARC, NSAutoreleasePool для старих реалізацій, що враховуються вручну).
Бред Ларсон

@Brad, це корисно, попередження зникли, я отримав кілька дзвінків виконувати SelectorInBackground.
п'ятий

11

Якщо ви використовуєте лише слабкі посилання для додаткової безпеки, викличте вручну нові функції середовища виконання, якщо вони доступні, і поверніться до простого присвоєння __unsafe_unretainedзмінним, якщо ні.

ZWRCompatibility.h дещо спростить це.


10

Завдяки бібліотеці сумісності Майка Еша PLWeakCompatibilty , тепер ви можете просто використовувати __weak і на iOS 4.x.

Це неймовірно просто налаштувати і не вимагає додаткових розглядів чи зусиль понад 5.x.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.