2016-01-29 5 views
3

Я встретил аналогичный вопрос в Swift Memory Management: Storing func in var, но это не решило мою проблему.Быстрое назначение функции var вызывает цикл сохранения?

Вот мое определение класса:

class Test { 
    var block: (() -> Int)? 

    func returnInt() -> Int { 
     return 1 
    } 

    deinit { 
     print("Test deinit") 
    } 
} 

Я попробовал два способа присвоить значение block собственности и получили совершенно другой результат. Второй подход не вызывал сохранить круг, который является довольно неожиданным:

var t = Test() 
// This will lead to retain cycle 
// t.block = t.returnInt 
// I thought this will also lead to retain cycle but actually didn't 
t.block = { 
    return t.returnInt() 
} 
t = Test() 

На мой взгляд, переменная t захватывается blockblock, а это свойство t, так может кто-нибудь объяснить, почему нет сохранить цикл?

+1

Интересно, что если вы не переназначить 'T' к чему-то еще и просто позволить ей выпасть из сферы, она ведет себя подобно сильный ссылочный цикл, если вы не включили '[unowned t] in' или' [weak t] in' ... – Rob

ответ

2

В Swift все захваченные переменные захватываются по ссылке (в терминологии Apple Blocks все захваченные локальные переменные: __block). Таким образом, t внутри блока используется совместно с t вне блока; блок не содержит независимую копию t.

Первоначально, есть сохранить цикл во втором случае тоже, как блок содержит ссылку на эту страницу общей копии t и t точек на первый Test объекта, и что block свойство указывает Test объекта к блоку. Однако, когда вы повторно назначаете общую переменную t (которая видна внутри и снаружи блока), вы прерываете цикл сохранения, потому что t больше не указывает на первый объект Test.


В первом случае, t эффективно захвачен значение, потому что t немедленно оценивается в выражении t.returnInt, а не быть захвачены в качестве переменной в блоке. Таким образом, переназначение t за пределами блока позже не влияет на блок и не прерывает цикл сохранения. Таким образом, вы можете думать о

t.block = t.returnInt 

, как вид, как

let tmp = t 
t.block = { 
    return tmp.returnInt() 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^