Комментарии 18
“Lines logged: 1”...“Lines logged: 4”??
Вроде будет “Lines logged: 2”...“Lines logged: 4”
Вроде будет “Lines logged: 2”...“Lines logged: 4”
Нужно было упомянуть и о capture list. Случай 4 тогда лечится таким способом:
var numberOfLinesLogged = 0
let logger1 = {[numberOfLinesLogged] in
numberOfLinesLogged += 1
print("Lines logged: \(numberOfLinesLogged)")
}
Нужно было упомянуть и о capture list.
Я в недоумении )) Вся публикация об этом. «Список захвата»
код
var numberOfLinesLogged = 0
let logger1 = {[numberOfLinesLogged] in
numberOfLinesLogged += 1
print("Lines logged: \(numberOfLinesLogged)")
}
Пробовали? В Playgroung ошибка компиляции
Left side of mutating operator isn't mutable: 'numberOfLinesLogged' is an immutable capture
Согласен, недоглядел. Но смысл в том, что [numberOfLinesLogged] захватывает значение переменной. У вас в статье это не указано.
var numberOfLinesLogged = 0
let logger1 = { [numberOfLinesLogged] in
print("Lines logged: \(numberOfLinesLogged)")
}
numberOfLinesLogged += 1
logger1()
Да, спасибо за любопытный момент, но, во-первых, это просто перевод, во-вторых, «сильный» захват упомянут в пункте 3, про ненамеренные действия в случае нескольких захваченных значений. Да, и мне не совсем ясен смысл capture list вообще без модификатора unowned или weak, ведь как раз его смысл — избегать циклов сильных ссылок. Руководство по Swift ясно говорит о том, что либо weak либо unowned должны быть:
А по факту получается, что можно и без модификатора. И, насколько я понимаю, имеет значение то, что numberOfLinesLogged — value-type.
Это все так, мои мысли вслух.
«Defining a Capture List
Each item in a capture list is a pairing of the weak or unowned keyword with a reference to...»
Отрывок из книги: Apple Inc. «The Swift Programming Language (Swift 5)». Apple Books.
А по факту получается, что можно и без модификатора. И, насколько я понимаю, имеет значение то, что numberOfLinesLogged — value-type.
Это все так, мои мысли вслух.
Да, и мне не совсем ясен смысл capture list вообще без модификатора unowned или weak, ведь как раз его смысл — избегать циклов сильных ссылок.
Для reference типов особо смысла нет, а для value типов есть.
https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID544
Что не так в этом примере?
В котором из?
случайно нажал на отправить. не успел дописать
здесь же все освободится и деинититься
func sing() -> () -> Void {
let taylor = Singer()
let singing = {
taylor.playSong()
return
}
return singing
}
здесь же все освободится и деинититься
Да, кстати. Но тут я виноват — вы же для тестирования используете sing()()? Это я уже от себя добавил, в оригинале этого не было. В этом случае освобождается и созданное замыкание, а вместе с ним деинится и taylor. Если использовать как автор написал
то в таком случае taylor «зависает»
Убрал из публикации sing()(). Спасибо.
let singFunction = sing()
singFunction()
то в таком случае taylor «зависает»
Убрал из публикации sing()(). Спасибо.
мммм да я делал с sing()()
Но! Мне кажется и в случае с
taylor освободится и деинитится. А вот SELF останется закепчуреный, да.
вот код для проверки
и лог с него
Кстати, а почему каунтер сразу 2 равен?
Но! Мне кажется и в случае с
let singFunction = sing()
singFunction()
taylor освободится и деинитится. А вот SELF останется закепчуреный, да.
вот код для проверки
func sing() -> () -> Void {
let taylor = Singer()
print("ARC count taylor = \(CFGetRetainCount(taylor))")
print("ARC count self = \(CFGetRetainCount(self))")
let singing = {
taylor.playSong()
print("Captured")
print("ARC count taylor = \(CFGetRetainCount(taylor))")
print("ARC count self = \(CFGetRetainCount(self))")
return
}
return singing
}
print("sing")
let singFunction = sing()
singFunction()
print("ARC count self = \(CFGetRetainCount(self))")
print("Finish")
и лог с него
sing
ARC count taylor = 2
ARC count self = 15
song playing
Captured
ARC count taylor = 2
ARC count self = 16
ARC count self = 16
Finish
I'm deinited
Кстати, а почему каунтер сразу 2 равен?
Как у меня выглядит лог в Playground (подсчёт ссылок на self закомментарен):
sing
ARC count taylor = 2
Shake it off!
Captured
ARC count taylor = 3
Finish
Не в курсе, расскажите!
sing
ARC count taylor = 2
Shake it off!
Captured
ARC count taylor = 3
Finish
Кстати, а почему каунтер сразу 2 равен?
Не в курсе, расскажите!
Хм, странно ) дкйствительно в плэйграунде счетчик ссылок повышается и не освобождается
Я не знаю ) Сам заметил только сейчас ) Раньше, мне казалось с 1 начиналось. Правда я это послежний раз делал ооочень давно
Не в курсе, расскажите!
Я не знаю ) Сам заметил только сейчас ) Раньше, мне казалось с 1 начиналось. Правда я это послежний раз делал ооочень давно
Я не знаю ) Сам заметил только сейчас ) Раньше, мне казалось с 1 начиналось. Правда я это послежний раз делал ооочень давно
stackoverflow
Хм, странно ) дкйствительно в плэйграунде счетчик ссылок повышается и не освобождается
Оборачиваем в «do»:
do {
print("sing")
let singFunction = sing()
singFunction()
print("Finish")
}
Получаем:
sing
ARC count taylor = 2
Shake it off!
Captured
ARC count taylor = 3
Finish
deinit…
Еще, как пример для избежания цикла ссылок — это создание контекста перед замыканием:
let context = (
parser: parser,
schema: schema,
titleLabel: titleLabel,
textLabel: textLabel
)
dataLoader.loadData(from: url) { data in
// We can now use the context instead of having to capture 'self'
let model = try context.parser.parse(data, using: context.schema)
context.titleLabel.text = model.title
context.textLabel.text = model.text
}
let context = (
parser: parser,
schema: schema,
titleLabel: titleLabel,
textLabel: textLabel
)
dataLoader.loadData(from: url) { data in
// We can now use the context instead of having to capture 'self'
let model = try context.parser.parse(data, using: context.schema)
context.titleLabel.text = model.title
context.textLabel.text = model.text
}
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Списки захвата в Swift: в чём разница между ссылками weak, strong и unowned?