Перевод ObjC-блоков в Swift Closures

Я пытаюсь перевести код objective-C в Swift. Я добавил Cocoapod "Masonry" для Autolayout в свой проект и добавил заголовок Bridging-Header, чтобы использовать objective-C Methods in Swift.

Этот метод ObjC:

[_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(self.view);
}];

должно быть чем-то вроде следующего закрытия:

tableView.mas_makeConstraints({ (make : MASConstraintMaker!) -> Void? in
    make.edges.equalTo(self.view)
})

Но я получаю сообщение "Не удалось найти член" mas_makeConstraints ", который не является ошибкой, поскольку метод индексируется, и автозаполнение дает мне следующее:

tableView.mas_makeConstraints(block: ((MASConstraintMaker!) -> Void)?)

?

Я делаю что-то не так здесь?

Ответ 1

Только мои 2 цента, если кто-нибудь столкнется с этим делом:

Это objc

[productView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(self.view.mas_left).with.offset(15);
    make.right.equalTo(self.view.mas_right).with.offset(15);
    make.top.equalTo(self.view.mas_top).with.offset(15);
    make.height.equalTo(productView.mas_width);
}];

превратится в

productView.mas_makeConstraints{ make in
    make.left.equalTo()(self.view.mas_left).with().offset()(15)
    make.right.equalTo()(self.view.mas_right).with().offset()(-15)
    make.top.equalTo()(self.view.mas_top).with().offset()(15)
    make.height.equalTo()(productView.mas_width)
    return ()
}

Ответ 2

Этот фрагмент здесь в сигнатуре метода:

(block: ((MASConstraintMaker!) -> Void)?)

... сообщает вам, что аргумент block является необязательным, а не возвращаемым значением, который должен быть Void (не Void?, где вы пишете (make: MASConstraintMaker!) -> Void?)

также: поскольку Swift Type Inference вам не нужно помещать типы в блок

также также: поскольку Swift Trailing Closures вам не нужно помещать замыкание, которое является последним аргументом метода внутри списка аргументов в parens (и поскольку здесь он является единственным аргументом, вы можете полностью покинуть парны)

так что действительно весь ваш вызов метода с аргументом блока может быть переписан как:

tableView.mas_makeConstraints { make in
    make.edges.equalTo(self.view)
}

наконец: похоже, что метод экземпляра, который вы вызываете на make.edges, возвращает блок, и благодаря удобной функции Swift для "неявного возврата отдельных блоков выражения" это может быть что ваш блок неявно возвращает значение этого выражения, когда он ожидает Void - поэтому в конце, если выше не работает, вам все равно нужно явно возвращать Void, написав вызов метода как:

tableView.mas_makeConstraints { make in
    make.edges.equalTo(self.view)
    return ()
}