Pull to refresh

Comments 18

“Lines logged: 1”...“Lines logged: 4”??
Вроде будет “Lines logged: 2”...“Lines logged: 4”
Имеется в виду, что мы добавили этот код после вызова logger1(). Но спасибо за внимательное чтение )
Нужно было упомянуть и о 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 должны быть:
«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. Если использовать как автор написал

let singFunction = sing()
singFunction()

то в таком случае taylor «зависает»
Убрал из публикации sing()(). Спасибо.
мммм да я делал с sing()()

Но! Мне кажется и в случае с
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

Кстати, а почему каунтер сразу 2 равен?

Не в курсе, расскажите!
Хм, странно ) дкйствительно в плэйграунде счетчик ссылок повышается и не освобождается

Не в курсе, расскажите!

Я не знаю ) Сам заметил только сейчас ) Раньше, мне казалось с 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
}
Отличное дополнение!
Sign up to leave a comment.

Articles