Как я могу избежать этого предупреждения в xcode. Вот фрагмент кода:
[player(AVPlayer object) addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)
queue:nil usingBlock:^(CMTime time) {
current+=1;
if(current==60)
{
min+=(current/60);
current = 0;
}
[timerDisp(UILabel) setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];///warning occurs in this line
}];
objective-c
cocoa-touch
automatic-ref-counting
avplayer
retain
user1845209
источник
источник
timerDisp
свойство в классе?player(AVPlayer object)
аtimerDisp(UILabel)
?Ответы:
Захват
self
здесь происходит с вашим неявным доступом к свойствуself.timerDisp
- вы не можете ссылаться на негоself
или на свойстваself
внутри блока, который будет строго сохранятьсяself
.Вы можете обойти это, создав слабую ссылку
self
перед доступомtimerDisp
внутри вашего блока:источник
__unsafe_unretained
вместо этого.self
, он сохраняется в основной очереди отправки. Я ошибся?И одну очень важную вещь, которую нужно помнить: не используйте переменные экземпляра непосредственно в блоке, используйте его как свойства слабого объекта, образца:
и не забудьте сделать:
другая проблема может появиться, если вы передадите слабую копию не сохраняемого кем-либо объекта:
Если
vcToGo
будет освобожден, а затем этот блок запущен, я думаю, вы получите сбой с нераспознанным селектором в корзину, котораяvcToGo_
теперь содержит переменную. Попробуйте это контролировать.источник
Лучшая версия
Так что все это будет так:
Я прочитал эту статью много раз. Это отличная статья Эрики Садун о том, как избежать проблем при использовании блоков и NSNotificationCenter
Быстрое обновление:
Например, в swift простой метод с успешным блоком будет:
Когда мы вызываем этот метод и нужно использовать
self
в блоке успеха. Мы будем использовать[weak self]
иguard let
функции.Этот так называемый сильный-слабый танец используется популярным проектом с открытым исходным кодом.
Alamofire
.Для получения дополнительной информации проверьте Swift-Style-Guide
источник
typeof(self) strongSelf = self;
за пределами блока (вместо __weak), а затем в блокеstrongSelf = nil;
после использования? Я не вижу, как ваш пример гарантирует, что уязвимость Self не равна нулю к моменту выполнения блока.В другом ответе Тим сказал:
Это не совсем так. Это нормально для вас, если вы прерываете цикл в какой-то момент. Например, предположим, у вас есть таймер, который запускает блок, который сохраняет себя, и вы также держите сильную ссылку на таймер в себе. Это прекрасно, если вы всегда знаете, что в какой-то момент вы уничтожите таймер и прервете цикл.
В моем случае только сейчас, у меня было это предупреждение для кода, который сделал:
Теперь я знаю, что clang выдаст это предупреждение, только если обнаружит, что метод начинается с «set» (и еще одного особого случая, о котором я не буду здесь упоминать). Для меня, я знаю, что нет опасности существования цикла сохранения, поэтому я изменил имя метода на «useY:». Конечно, это может не подходить во всех случаях, и обычно вы захотите использовать слабую ссылку, но Я думал, что стоит отметить мое решение на случай, если оно поможет другим.
источник
Много раз, это на самом деле не цикл сохранения .
Если вы знаете, что это не так, вам не нужно приносить бесплодных слабых себя в мир.
Apple даже навязывает нам эти предупреждения с помощью API к ним
UIPageViewController
, который включает метод set (который вызывает эти предупреждения - как упоминалось в другом месте - думая, что вы устанавливаете значение для ивара, который является блоком) и блок обработчика завершения (в котором Вы, несомненно, будете обращаться к себе).Вот некоторые директивы компилятора, чтобы удалить предупреждение из этой одной строки кода:
источник
Добавление двух центов на улучшение точности и стиля. В большинстве случаев вы будете использовать
self
в этом блоке только одного или нескольких членов , скорее всего, просто для обновления слайдера. Кастингself
излишним. Вместо этого лучше быть явным и приводить только те объекты, которые вам действительно нужны внутри блока. Например, если этоUISlider*
, скажем, экземпляр_timeSlider
, просто сделайте следующее до объявления блока:Тогда просто используйте
slider
внутри блока. Технически это более точно, так как сужает потенциальный цикл сохранения только к нужному объекту, а не ко всем объектам внутри.self
.Полный пример:
Кроме того, наиболее вероятно, что объект, приводимый к слабому указателю, уже является слабым указателем внутри,
self
а также минимизирует или полностью исключает вероятность сохранения цикла. В приведенном выше примере_timeSlider
это свойство хранится как слабая ссылка, например:С точки зрения стиля кодирования, как и в C и C ++, объявления переменных лучше читать справа налево. Декларирование
SomeType* __weak variable
в таком порядке читает более естественно справа налево , как:variable is a weak pointer to SomeType
.источник
Недавно я столкнулся с этим предупреждением и хотел понять его немного лучше. После небольшой проб и ошибок я обнаружил, что это происходит из-за того, что метод начинается с «add» или «save». Цель C рассматривает имена методов, начинающиеся с «new», «alloc» и т. Д., Как возвращение сохраненного объекта, но не упоминает (что я могу найти) что-либо о «add» или «save». Однако, если я использую имя метода таким образом:
Я увижу предупреждение в строке [self done]. Однако это не будет:
Я пойду дальше и буду использовать способ «__weak __typeof (self) weakSelf = self», чтобы ссылаться на мой объект, но на самом деле мне не нравится делать это, так как это может сбить с толку будущего меня и / или другого разработчика. Конечно, я также не мог бы использовать «добавить» (или «сохранить»), но это еще хуже, поскольку он убирает смысл метода.
источник