1

В Objective-C вы можете использовать переменную экземпляра внутри блока и сохранить этот блок в самом объекте. Если вы сделаете это, вы столкнетесь с довольно хлопот, чтобы убедиться, что вы не создаете циклическую зависимость, и, чтобы заставить замолчать все предупреждения компилятора:Есть ли какой-либо путь помимо слабого/сильного танца, чтобы использовать переменную экземпляра в блоке?

@implementation TestBlock { 
    int someVariable; 
    void (^someBlock)(); 
} 

- (void) createBlock 
{ 
    // ideally I would like to use: 
    someBlock = ^{ 
     someVariable++; 
    }; 

    // but in reality I need to use: 
    TestBlock * __weak weakSelf = self; 
    someBlock = ^{ 
     TestBlock *strongSelf = weakSelf; 
     strongSelf->someVariable++; 
    }; 
} 

@end 

Если weakSelf используется вместо strongSelf, то вы» будет получать сообщение об ошибке:

Dereferencing a __weak pointer is not allowed

Если вы используете self непосредственно, а затем сохранить цикл создается.

Я знаю, почему это необходимо, но действительно ли нет более простого способа использовать переменную экземпляра внутри блока? Любые практические подходы, которые вы использовали, чтобы сделать это более коротким и читаемым?

+1

У вас нет другого выхода для прямого доступа к ivar. Но у вас есть возможность использовать свойство вокруг ivar. Затем вы можете получить доступ к свойству с помощью 'wealSelf'. – rmaddy

+0

Если вам нужно получить доступ к ivar, вы можете использовать макросы «@weakify» и «@strongify» , что делает его немного более удобочитаемый. –

+0

Суть заключается в том, чтобы избежать блоков в качестве иваров. Например, вы можете перепроектировать свой класс, чтобы он мог иметь методы, которые принимают блок как параметр. – CouchDeveloper

ответ

2

Если вы создаете property для своего ivar, вы можете ссылаться на это свойство непосредственно на ссылку weak (хотя это фактически вызов метода). Если вы хотите получить доступ к переменной экземпляра напрямую, вам необходимо сделать танец weak/strong, который у вас есть в вашем опубликованном коде.

Я понимаю, что это вопрос Objective-C, но стоит отметить, что проблема заключается в том, что capture lists в Swift разрешает.

+0

Конечно, доступ к свойствам, когда вы просто хотите увеличить int, - это скорее боль в задней части: '[self setSomeVariable: [self someVariable] + 1];' –

+1

Это действительный синтаксис свойства Objective-C для записи 'self. someVariable = self.someVariable + 1; ' –

+0

Это даже допустимый синтаксис для написания' self.someVariable ++'. Но, по предположению вопроса, невероятно редко, что создание ивара напрямую - хорошая идея. Еще менее распространено, что доступ к нему с помощью '->' является хорошей идеей. Свойства - это правильный способ реализовать все это. (Хотя в большинстве случаев свойства по-прежнему требуют немного сильных/слабых танцев. Как предлагает CouchDeveloper, лучше всего попытаться спроектировать вокруг этого, если сможете.) –