Почему в замыкании функции `makeConstraints` от SnapKit нет` self`?

starLabel.snp.makeConstraints { make in
    make.left.equalTo(starImageView.snp.right).offset(5)
    make.centerY.equalToSuperview()
}

starImageView а также starLabel свойства текущего контроллера представления. Но почему я могу игнорировать self(self.starImageView) в закрытии, которое является параметром в makeConstraints?

И в моем закрытии я должен написать self явно, или компилятор сообщит об ошибке:

Ссылка на свойство 'starImageView' в закрытии требует явного 'self'. сделать семантику захвата явной

Вставьте "я".

1 ответ

public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
        ConstraintMaker.makeConstraints(item: self.view, closure: closure)
}

Потому что закрытие не @escaping, Это означает, что закрытие будет просто выполняться в функции. Когда функция над закрытием будет выпущена. Только функция может удерживать закрытие.

Это потому что equalTo выглядит так:

public func equalTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
    return self.relatedTo(other, relation: .equal, file: file, line: line)
}

А также ConstraintRelatableTarget это протокол, который приводит к различным типам, как Int, Float и т. д. У вас также есть ссылка на ConstraintItem в данном случае это тот вид, на который вы ссылаетесь, и вот так он выглядит:

internal weak var target: AnyObject?
internal let attributes: ConstraintAttributes

internal init(target: AnyObject?, attributes: ConstraintAttributes) {
    self.target = target
    self.attributes = attributes
}

internal var layoutConstraintItem: LayoutConstraintItem? {
    return self.target as? LayoutConstraintItem
}

Как оказалось, оба Any? а также AnyObject? (Я не думаю, что это должно быть необязательным), не нужно, чтобы я был достигнут. Следовательно, все, что вы положили в equalTo функция, видна snapKit как AnyObject? и для этого не нужно self ссылка.

Другие вопросы по тегам