Diberikan:
typealias Action = () -> ()
var action: Action = { }
func doStuff(stuff: String, completion: @escaping Action) {
print(stuff)
action = completion
completion()
}
func doStuffAgain() {
print("again")
action()
}
doStuff(stuff: "do stuff") {
print("swift 3!")
}
doStuffAgain()
Apakah ada cara untuk membuat completion
parameter (dan action
) bertipe Action?
dan juga menyimpannya @escaping
?
Mengubah jenisnya memberikan kesalahan berikut:
Atribut @escaping hanya berlaku untuk tipe fungsi
Menghapus @escaping
atribut, kode mengkompilasi dan menjalankan, tetapi tampaknya tidak benar karena completion
penutupan keluar dari ruang lingkup fungsi.
@escaping
atribut, kode mengkompilasi dan menjalankan" - Itu karena, seperti yang dijelaskan dalam SR-2444 ,Action?
secara default, melarikan diri. Jadi, melepas@escaping
ketika menggunakan penutupan opsional memenuhi apa yang Anda butuhkan.Jawaban:
Ada pelaporan SR-2552 yang
@escaping
tidak mengenali jenis fungsi alias. itu sebabnya kesalahan@escaping attribute only applies to function types
. Anda bisa mengatasinya dengan memperluas jenis fungsi di tanda tangan fungsi:EDIT 1 ::
Saya sebenarnya di bawah versi beta xcode 8 di mana bug SR-2552 belum diselesaikan. memperbaiki bug itu, memperkenalkan bug baru (yang Anda hadapi) yang masih terbuka. lihat SR-2444 .
Solusinya @Michael Ilseman menunjuk sebagai solusi sementara adalah menghapus
@escaping
atribut dari tipe fungsi opsional, yang menjaga fungsi sebagai melarikan diri .EDIT 2 ::
The SR-2444 telah ditutup menyatakan secara eksplisit bahwa penutupan di posisi parameter tidak melarikan diri dan membutuhkan mereka harus ditandai dengan
@escaping
untuk membuat mereka melarikan diri, tetapi parameter opsional yang secara implisit melarikan diri, karena((Int)->())?
merupakan sinonim dariOptional<(Int)->()>
, penutupan opsional melarikan diri.sumber
@escaping may only be applied to parameters of function type func doStuff(stuff: String, completion: (@escaping ()->())?) {
a temporary solution is remove the @escaping attribute from optional function type, that keep the function as escaping.
Bisakah Anda menjelaskan ini lebih lanjut? Semantik default di swift 3 adalah non-escape. Walaupun ia mengkompilasi tanpa @escaping saya khawatir ini akan menyebabkan masalah dengan diperlakukan sebagai non-escaping. Apakah itu tidak benar?@autoclosure
? Satu mendapat kesalahan yang sama di sana ...dari: milis swift-pengguna
Jadi parameter fungsi opsional adalah @escaping secara default.
@noecape hanya berlaku untuk parameter fungsi secara default.
sumber
(()->Void)?
itu sama dengan mengatakan Anda milikiOptional<()->Void>
dan agar untukOptional
mempertahankan kepemilikan itu harus hanya menerima@escaping
fungsi. Saya akan ketiga bahwa ini harus menjadi jawaban yang diterima. Terima kasih.Saya mengalami masalah yang sama karena pencampuran
@escaping
dan non@escaping
-sangat membingungkan, terutama jika Anda harus melewati penutupan.Saya akhirnya memberikan nilai default no-op ke parameter penutupan via
= { _ in }
, yang menurut saya lebih masuk akal:sumber
Saya membuatnya bekerja di Swift 3 tanpa peringatan apa pun hanya dengan cara ini:
sumber
Yang penting untuk memahami dalam contoh adalah bahwa jika Anda mengubah
Action
keAction?
penutupan yang melarikan diri. Jadi, mari kita lakukan apa yang Anda usulkan:Oke, sekarang kita akan menelepon
doStuff
:Nah, persyaratan itu hanya muncul untuk lolos dari penutupan. Jadi penutupannya keluar. Itu sebabnya Anda tidak menandainya melarikan diri - itu sudah melarikan diri.
sumber