Обновление свойства NSUInteger в блоке.Предупреждение: блок будет сохранен - PullRequest
3 голосов
/ 22 февраля 2012

У меня NSUInteger определен как свойство следующим образом:

@property (nonatomic, assign) NSUInteger wordDisplayed;

Мне нужно иметь это свойство, поскольку мне нужен доступ для чтения / записи в эту переменную из других методов и классов.

При попытке изменить значение этого свойства в блоке я получаю следующее предупреждение:

Сильный захват "self" в этом блоке может привести к циклу сохранения

«Блок будет сохранен объектом, сильно удерживаемым захваченным объектом» *

Как обновить это свойство переменной в блоке?

Блок, который я использую, находится в измененном UIActionSheet, который я использую, чтобы заставить UIActionSheet принимать блоки.

https://github.com/zoul/Lambda-Alert

Вот примермой код:

 sectionHeadersAct = [[LambdaSheet alloc] initWithTitle:@"Book 2 Lesson 1"];
    [sectionHeadersAct addButtonWithTitle:@"D. E. F. & G. Teach New Letters" block:^{ 
        wordDisplayed = 15; //This is where I'm trying to change the value
    }];

[sectionHeadersAct showInView:self.view];

Ответы [ 2 ]

4 голосов
/ 22 февраля 2012

Этот пост посвящен этой конкретной проблеме: https://stackoverflow.com/a/8159567/656036

Подводя итог: вы должны использовать слабый указатель на себя. Если вы используете ARC, вы можете решить эту проблему, написав это перед вашим блоком:

__weak MyObject *weakSelf = self;

И использование самого блока вместо самого себя в самом блоке.

РЕДАКТИРОВАТЬ Попробуйте это:

__weak ViewController *weakSelf = self;
sectionHeadersAct = [[LambdaSheet alloc] initWithTitle:@"Book 2 Lesson 1"];
[sectionHeadersAct addButtonWithTitle:@"D. E. F. & G. Teach New Letters" block:^{ 
    weakSelf.wordDisplayed = 15;
}];

[sectionHeadersAct showInView:self.view];
3 голосов
/ 22 февраля 2012

Это обычное явление при использовании блоков.Я предполагаю, что вы обращаетесь к свойству с блоком с помощью чего-то вроде self.wordDispalyed.

Поскольку блоки могут выполняться асинхронно, они содержат сильную ссылку на объекты внутри них.Это так, что если они запускаются через некоторое время после того, как вы освободили объект, по крайней мере, блок все еще может отправлять ему сообщения.

В вашем случае вы ссылаетесь на свойство внутри блока.Таким образом, блок сохраняет объект, в данном случае self.Но ваш объект (self) также сохраняет блок, так как он должен его запустить.Итак, у вас есть круговая ссылка.Блок сохраняет объект, а объект сохраняет блок.Это может вызвать у вас проблемы - и компилятор предупреждает вас об этом.

Чтобы обойти это, вам нужно создать локальную переменную, которая будет хорошо сохраняться блоком, и использовать ее дляссылка на имущество.Это просто, как написать:

__weak TheObject *blockSelf = self;

И затем в вашем блоке вы имеете дело со свойством как:

blockSelf.wordDisplayed …
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...