Стоит внимательно взглянуть на политику управления памятью .Дело в том, что (как мне кажется), когда ваш код назначает строку adsName, объект, частью которого является метод preloadNextRewardVideo
, не становится владельцем объекта string, на который указывает adsName
(«владение»).в этом контексте означает либо выделение и инициализацию пространства для него с помощью alloc / init, new, copy и т. д., либо отправку ему явного сообщения сохранения).Все, что у вас есть, это локальная переменная, которая указывает на строковый объект, принадлежащий массиву _allRewardVideoAds
.Да, выполнение присваивания увеличивает количество сохранений, но это сохранение автоматически высвобождается и ограничивается областью применения этого метода.Как только этот метод завершится, ничему не будет принадлежать этот строковый объект, и он будет освобожден.
Это не будет проблемой (и не создаст флаг NSZombie), за исключением того, что вы только что отправили adsName
к другому объекту (GADRewardBasedVideoAd* ads
), который, как я предполагаю, тоже не сохраняет его.Конечно, ads
также автоматически освобождается (ничто не владеет им вне этого метода), но что это, состояние гонки по поводу того, сначала ли ads
или adsName
освобождается?Я подозреваю, что у вас действительно есть состояние гонки, потому что NSZombie появляется только иногда, но я недостаточно знаю о внутренних механизмах автоматического выпуска, чтобы знать, как это может работать.
Я думаю, что NSZombie просто говорит вам, что у вас есть объект, который:
- используется внешним объектом и
- из-за скорого уничтожения, хотяautorelease.
ARC ожидает проблему и использует NSZombie, чтобы сообщить вам.
Вы можете исправить это либо с помощью установщика свойств (например, используйте self.currentRewardVideoName = adsName
), который сохраняет строку-объект глобально для этого объекта или локально скопировав его (NSString* adsName = [[_allRewardVideoAds objectAtIndex:0] copy]
), который гарантирует, что ваш объект владеет строкой до конца метода.