Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp

>100 Views

September 28, 16

スライド概要

Swift 3 の新しくなったところのうちから、目立つところを6つほど、意味的な観点を大事にしながらざっくり紹介しました。2016/09/28 ISAO meetup でお話しした発表資料です。

※ Docswell での公開に移行する直前の Slideshare での閲覧数は 3,433 でした。

profile-image

正統派趣味人プログラマー。プログラミングとは幼馴染です。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ ද໘͔Β‫͜ͱ͍͘ʹ͑ݟ‬ΖΛத৺ʹ঺հ *4"0.FFUVQPO &;/&5‫۽‬୩༑޺ IUUQF[OFUKQ 4XJGU

2.

‫۽‬୩༑޺ 5PNPIJSP,VNBHBJ ⾣ 4XJGU‫͕ޠݴ‬௒େ޷͖Ͱ͢ʂ ⾣ ΈΜͳͰָ͠Ήษ‫ڧ‬ձ͕େ޷͖Ͱ͢ʂ ⾣ ϓϩάϥϛϯάͷָ͠͞Λ఻͍͖͍͑ͯͨɻ !FT@LVNBHBJ UPNPIJSPLVNBHBJ $PEF1JFDFGPSNBD04 IUUQF[OFUKQ 9DPEFపఈղઆ

3.

$PEF1JFDFGPSNBD04 ษ‫ڧ‬ձΛָ͠ΉΞϓϦ ⾣ ιʔείʔυΛ5XJUUFSͱ(JTUʹಉ࣌౤ߘ ⾣ ίʔυཝΛۭʹ͢Ε͹ɺී௨ʹπΠʔτՄೳ ⾣ ϋογϡλάΛઃఆͰ͖Δʗ෇͚๨Εͳ͍ #swift

4.

ษ‫ڧ‬ձΛ։࠵͍ͯ͠·͢ɻ Θ͍Θ͍ɺָ͘͠ɺ ΈΜͳͰ‫ޠ‬Β͑Δ৔ॴΛ໨ࢦͯ͠ ԣ඿J1IPOF։ൃऀษ‫ڧ‬ձ ୈճ໨͸݄೔ͷ։࠵ʢ໨ඪʣ ZJEFW ˏԣ඿ɾഅंಓ IUUQTBUOEPSHHSPVQTZJEFW ΧδϡΞϧ4XJGUษ‫ڧ‬ձ ΈΜͳͰ4XJGU ෮शձ DTXJGU !ԣ඿ɾ੨༿୆ NJOOB@EF@TXJGU ˏौ୩ ୈճ໨Λ݄೔ʹ։࠵ ୈճ໨͸݄೔ʹ։࠵༧ఆ IUUQTBUOEPSHHSPVQTDTXJGU IUUQDTXJGUDPOOQBTTDPN

5.

NPPLNPPLSBEJP Ќ൛ ϜοΫϜοΫϥδΦ ‫۽‬୩ͱ៸໘͕ϓϩάϥϛϯάίʔυͷ಺͔Β ௌ͑ͯ͘͜Δ੠ʹࣖΛ܏ָ͚ͯ͠ΉϥδΦ ຖ݄ୈ̎ɾୈ̐ ݄༵೔ ʹ഑৴ IUUQNPPLNPPLSBEJPDPNB ⾣ ୈ̍࿩ ʰϓϩάϥϛϯάͱࢲͨͪʱ ⾣ ୈ̎࿩ ʰྻ‫ܕڍ‬ʱ ⾣ ୈ̏࿩ ʰίϝϯτʱ ⾣ ୈ̐࿩ ʢ݄೔ʹ഑৴༧ఆʣ

6.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ ද໘͔Β‫͜ͱ͍͘ʹ͑ݟ‬ΖΛத৺ʹ঺հ

7.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ ද໘͔Β‫͜ͱ͍͘ʹ͑ݟ‬ΖΛத৺ʹ঺հ  4XJGUͷίϯηϓτ          "1*໋໊‫ن‬ଇͷओͳͱ͜Ζ        *NQMJDJUMZ6OXSBQQFE0QUJPOBM      4FRVFODFͷ৽‫ػ‬ೳ       ΠϯσοΫε͸$PMMFDUJPO੍͕‫ ޚ‬     !OPFTDBQFΫϩʔδϟʔ          

8.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ 4XJGUͷίϯηϓτ

9.

4XJGUͷίϯηϓτ 4XJGUͷ໨ඪ ⾣ 4XJGU‫ޠݴ‬Λ֬ఆɾख़੒ͤ͞Δ ͦͷͨΊʹ͸ιʔε‫׵ޓ‬ੑͷഁյ΋ࣙ͞ͳ͍ ⾣ 4XJGUҎ߱Ͱͷ ιʔείʔυͷ‫׵ޓ‬ੑΛ໨ࢦ͢ʢ౒ྗ໨ඪʣ ⾣ 4XJGUҎ߱ͷιʔε‫׵ޓ‬ഁյ͸ Ө‫࠷͕ڹ‬খ‫ͳʹݶ‬ΔΑ͏ʹ഑ྀ͢Δ

10.

4XJGUͷίϯηϓτ ஫໨͍ͨ͠ͱ͜Ζ ⾣ ৽͍͠"1*ΨΠυϥΠϯ ⾣ ‫༷࢓ޠݴ‬Λચ࿅ ⾣ 0CKFDUJWF$΍$ͷίʔυΛ4XJGUจԽʹ༥߹ ⾣ ίϯύΠϥ΍*%&ͷ඼࣭޲্ ⾣ 4XJGUύοέʔδϚωʔδϟʔ

11.

4XJGUͷίϯηϓτ ண஍఺ ‫ࣗޠݴ‬ମͷ҆ఆԽΛਤΓ ଞ‫΁ڥ؀‬ͷҠ২ੑΛ‫ݟ‬ਾ͑Δ

12.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ "1*໋໊‫ن‬ଇͷओͳͱ͜Ζ

13.

"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ 4XJGU"1*%FTJHO(VJEFMJOFT ⾣ 4XJGUͷ"1*Λॻͨ͘Ίͷࢦ਑ ⾣ 4XJGUͷ໨ཱͬͨมԽ͕ू໿͞Ε͍ͯΔҹ৅ IUUQTTXJGUPSHEPDVNFOUBUJPOBQJEFTJHOHVJEFMJOFT

14.

"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ "1*%FTJHO(VJEFMJOFT֓ཁ ⾣ ࣗવͳӳ‫Ͱޠ‬௲ΕΔΑ͏ʹ ⾣ શͯͷ‫ݴ‬༿͕໌֬ͳҙຯΛ‫ؚ‬ΉΑ͏ʹ ⾣ ໊લͷ෇͚ํ w ϑΝΫτϦʔϝιουͱΠχγϟϥΠβʔ w ϝιουʢ෭࡞༻Λ൐͏৔߹ɺ൐Θͳ͍৔߹ʣ w ਅِ஋Λฦ͢৔߹ w ϓϩτίϧ w ઐ໳༻‫ޠ‬ͷ࢖͍Ͳ͜Ζ w Φʔόʔϩʔυ΍‫ط‬ఆ஋ͷར༻ʹ͍ͭͯ ⾣ େҬؔ਺ΑΓ΋ϝιου༏ઌͰఆٛ͢Δ

15.

4XJGU"1*%FTJHO(VJEFMJOFT ಛʹ஌͓͖͍ͬͯͨͱ͜Ζ

16.

"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ ‫໊ܕ‬΍ม਺໊ ⾣ Ұൠʹɺ໊લ͸໊ࢺͰ͚ͭΔ ⾣ ਅِΛද͢ϓϩύςΟʔ໊͸ɺର৅ͷओுͰද‫͢ݱ‬Δ // 型は名詞で名前をつける。 struct Queue { … } // 変数名は名詞でつける。 let queue = Queue() // 真偽値プロパティーは主張重視。配列が空であるか。 items.isEmpty

17.

"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ ϝιουͱϥϕϧ෇͚ ⾣ ѻ͏ओମ͸ϥϕϧΛল͘ͱɺࣗવͳද‫ͳʹݱ‬Δ ⾣ ҐஔಛఆͳͲͷલஔࢺ͸ϥϕϧͰද‫͢ݱ‬Δ // item は items が扱う主体 items.add(item) // index は items が扱う主体ではない items.remove(at: index) // 複数で位置を示すときは前置詞を名前に含めることも items.moveTo(x: 3, y: 5)

18.

"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ ؔ਺໊͸ࣗ਎΁ͷӨ‫ʹڹ‬Αͬͯ ⾣ ࣗ਎΁ͷӨ‫͕͋ڹ‬Δ͔Ͱɺ໊લΛม͑Δ ⾣ ໊લ໊͕ࢺ‫͔ܥ‬ಈࢺ‫Ͱ͔ܥ‬ɺ໋໊ํ๏͕มΘΔ // 名詞系で、自身に影響しない場合は、名詞そのまま。 let answer = value.squareRoot() // 名詞系で、自身に影響する場合は“form”接頭辞。 value.formSquareRoot() // 動詞系で、自身に影響ないなら“-ed”か“-ing”接尾辞。 let answer = value.divided(by: 3) // 動詞系で、自身に影響するなら、動詞そのまま。 value.divide(by: 3)

19.

"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ ਅِΛ൑ఆ͢Δϝιου໊ ⾣ ର৅ͷओுͱͯ͠἞ΈऔΕΔ໊લʹ͢Δ ⾣ ී௨ͷϝιουͱ͸ผͷ‫ن‬ଇͰ໊લΛ͚ͭΔ // 範囲が、ある範囲と、重なる点があるか if range1.overlaps(range2) { … } // 配列が、要素を、含んでいるか if items.contains(item) { … } // 要素を返してるのか、要素を含むか判定してるのか。 let answer = items.contained(item) { … }

20.

"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ ྻ‫ࢠڍ‬ͷ໊લ͸খจࣈ ⾣ -PXFS$BNFM$BTFͰ໊લΛ͚ͭΔ // 列挙子の名前は小文字で始める。 enum Drink { case coffee case tea case water }

21.
[beta]
"1*໋໊‫ن‬ଇͷओͳͱ͜Ζ

େҬؔ਺ΑΓ΋ϝιουͰ
⾣ ϝιουͳΒɺॴଐͰҙຯ͕໌ྎʹͳΔ
⾣ ॴଐ͕ͳ͍ͱ͖΍‫׳‬शతʹద੾ͳΒɺେҬؔ਺Λ࢖͏

// キューの最初、と表現できる。

extension Queue {
func first -> Element? { … }
}
// 所属が定まらない場合に、大域関数として扱う。

func max(_ x: Int, _ y: Int, _ z: Int)
// 数値の絶対値、所属はあっても abs(x) が慣習的。

func abs(_ x: Int) -> Int

22.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ *NQMJDJUMZ 6OXSBQQFE 0QUJPOBM

23.

*NQMJDJUMZ 6OXSBQQFE 0QUJPOBM *NQMJDJUMZ6OXSBQQFE0QUJPOBMͱ͸ ⾣ த਎Λ҉໧తʹΞϯϥοϓͯ͘͠ΕΔΦϓγϣφϧ ⾣ ࢖͏·Ͱʹ͸ઈରʹ஋Λ༻ҙͰ͖Δ৔໘Ͱศར class Controller : UIViewController { @IBOutlet var titleLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() titleLabel.text = "ISAO meetup" } } ! や ? で中身を取り出す操作をしなくても 自動で取り出される

24.

*NQMJDJUMZ 6OXSBQQFE 0QUJPOBM %FQSFDBUFE let value: Type! ⾣ 0QUJPOBM *60ଐੑͱ͍͏ཱͪҐஔʹมߋ w ҉໧ΞϯϥοϓͳΦϓγϣφϧ‫ܕ‬͸ഇࢭ ʢ༧ఆʁʣ ⾣ Type!ͷΑ͏ͳఆٛࣗମ͸݈ࡏ ⾣ ม਺Λ௚઀࢖͏ͱɺ҉໧Ξϯϥοϓʢैདྷ௨Γʣ ⾣ ‫ܕ‬ਪ࿦Ͱ͸Type?ͱͯ͠ѻΘΕΔ ⾣ ‫ܕ‬ύϥϝʔλʔʹ͸࢖͑ͳ͍ʢϧʔϧ্ʣ

25.

*NQMJDJUMZ 6OXSBQQFE 0QUJPOBM ม਺ఆٛͱ‫ܕ‬ਪ࿦ ⾣ ม਺ఆٛ͸ɺࠓ·ͰͲ͓ΓՄೳ ⾣ ଞͷม਺ʹ୅ೖ͢Δͱɺී௨ͷ0QUJPOBMʹͳΔ // 型に ! を添えて定義する(従前どおり) let implicitly: Int! = 100 // 型明記せずに受けると、その変数は普通の Optional 型 let optional = implicitly Int?

26.
[beta]
*NQMJDJUMZ 6OXSBQQFE 0QUJPOBM

ෆ༻ҙʹ࣋ͪӽ͞ͳ͍޻෉ 
⾣ ผͷม਺ʹ࣋ͪग़͢ͱ͖ʹOJMͷѻ͍Λ໌֬Խ
⾣ ଈ࣌ղফ͢Δ͔ɺ໌ࣔΞϯϥοϓঢ়ଶͰ࣋ͪӽ͔͢

// Int! を返す関数があったとき …

func something() -> Int! {…}
// 暗黙アンラップとして即使用する方法(受け手は戻り値の型)

let result = something().advanced(by: 1)
// 速やかに解消する方法(受け手は Int 型)

let result = something()!
// nil の可能性を残して先へ(受け手は Int? 型)

let result = something()

27.

*NQMJDJUMZ 6OXSBQQFE 0QUJPOBM ෆ༻ҙʹ࣋ͪӽ͞ͳ͍޻෉  ⾣ ‫ܕ‬ύϥϝʔλʔʹ͸࢖͑ͳ͍ʢ͜ͱʹͳ͍ͬͯΔʣ ⾣ જࡏతʹOJM͕࣋ͪӽ͞ΕΔՄೳੑΛճආ let values = Array<Int!> JNQMJDJUMZVOXSBQQFEPQUJPOBMTBSFPOMZ BMMPXFEBUUPQMFWFMBOEBTGVODUJPOSFTVMUT // Int! 型のまま持ち歩くのを防ぐことで、 // 取り出した時に初めて nil だったことに気づくのを予防

28.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ 4FRVFODFͷ৽‫ػ‬ೳ

29.

4FRVFODFͷ৽‫ػ‬ೳ γʔέϯεͱ͸ ⾣ 4FRVFODFϓϩτίϧʹ४‫ܕͨ͠ڌ‬ ⾣ GPSʜJOߏจͰ‫܁‬Γฦ͠ॲཧ͕Ͱ͖Δ for value in 0 ..< 100 { } CountableRange<Int> : Sequence

30.

4FRVFODFͷ৽‫ػ‬ೳ खܰʹѻ͏ͨΊͷ‫ػ‬ೳ ⾣ γʔέϯε‫ܕ‬Λ؆୯ʹ࡞Δ w TFRVFODF pSTUOFYU  w TFRVFODF TUBUFOFYU  ⾣ ৚݅ʹ͋ͬͨཁૉΛ‫͚ͭݟ‬Δ w pSTU XIFSF

31.

γʔέϯεΛ࡞Δ

32.

γʔέϯεΛ࡞Δ ϑΟϘφον਺ྻΛ࡞Δͱ͖ 1 1 1 1 2 2 3 5 1 1 1 1 3 " ࣗ࡞ͷ4FRVFODF‫࡞Ͱܕ‬੒ # "OZ4FRVFODFͰ࡞੒ $ TFRVFODF pSTUOFYU Ͱੜ੒ % TFRVFODF TUBUFOFYU Ͱੜ੒ 1

33.
[beta]
γʔέϯεΛ࡞Δ

"ࣗ࡞ͷ4FRVFODF‫࡞Ͱܕ‬੒
struct Fibonacci : Sequence {
struct Iterator : IteratorProtocol {
fileprivate var data = (0, 1)
mutating func next() -> Int? {
defer {
data = (data.1, data.0 + data.1)
}
return data.1
}
}
func makeIterator() -> Iterator {
return Iterator()
}
}

34.
[beta]
γʔέϯεΛ࡞Δ

#"OZ4FRVFODFͰ࡞੒
let fibonacci = AnySequence { () -> AnyIterator<Int> in
var data = (0, 1)
return AnyIterator {
defer {
data = (data.1, data.0 + data.1)
}
return data.1
}
}

35.

γʔέϯεΛ࡞Δ $TFRVFODF pSTUOFYU Ͱੜ੒ var previous2 = 0 let fibonacci = sequence(first: 1) { previous1 in defer { previous2 = previous1 } return previous1 + previous2 }

36.
[beta]
γʔέϯεΛ࡞Δ

%TFRVFODF TUBUFOFYU Ͱੜ੒
let fibonacci = sequence(state: (0, 1)) {
(state: inout (Int, Int)) -> Int? in
defer {
state = (state.1, state.0 + state.1)
}
return state.1
}

37.

৚݅ʹ͋ͬͨཁૉΛ‫͚ͭݟ‬Δ

38.

৚݅ʹ͋ͬͨཁૉΛ‫͚ͭݟ‬Δ ࢦఆ৚݅Λ࠷ॳʹຬͨ͢஋ ⾣ Ҏલ͸GPSʜJOͰ୳͢ඞཁ͕͋ͬͨ ⾣ 4XJGUͰ͸pSTU XIFSF Ͱ୳ͤΔ // Swift 3 での探し方 let value: Int? = fibonacci.first { $0 > 100 } // Swift 2 での探し方 var value: Int? { for v in fibonacci where v > 100 { return v } return nil }

39.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ ΠϯσοΫε͸$PMMFDUJPO੍͕‫ޚ‬

40.

ΠϯσοΫε੍‫ޚ‬͸$PMMFDUJPO͕୲౰ 4XJGUͰ͸ΠϯσοΫε͕୲౰ ⾣ Ҏલ͸ΠϯσοΫεࣗମ͕લ‫܎ؔޙ‬Λ೺Ѳ͍ͯͨ͠ ⾣ 'PSXBSE*OEFY #JEJSFDUJPOBM*OEFY ʜ // 次のインデックスを取得 let next = index.successor() // 前のインデックスを取得 let previous = index.predeessor()

41.

ΠϯσοΫε੍‫ޚ‬͸$PMMFDUJPO͕୲౰ 4XJGUͰ͸ίϨΫγϣϯ͕୲౰ ⾣ ࠓ‫ޙ‬͸ίϨΫγϣϯ͕લ‫܎ؔޙ‬Λ೺Ѳ͢Δ ⾣ $PMMFDUJPO #JEJSFDUJPOBM$PMMFDUJPO ʜ // 扱うインデックスの範囲 let indices = items.indices // あるインデックスの次を取得 let next = items.index(after: index) // あるインデックスの前を取得 let previous = items.index(before: index)

42.

ΠϯσοΫε੍‫ޚ‬͸$PMMFDUJPO͕୲౰ ΠϯσοΫε੍͕‫͢ޚ‬ΔσϝϦοτ ⾣ ΠϯσοΫε͕࿈ଓੑΛද‫͚ͳ͠ݱ‬Ε͹͍͚ͳ͍ ⾣ ࣮࣭ɺίϨΫγϣϯຖʹΠϯσοΫε‫͕ܕ‬ඞཁ ໊฽‫ܕ‬ͷΠϯσοΫε Kudo Kumagai predecessor successor Sato Tanaka successor

43.

ΠϯσοΫε੍‫ޚ‬͸$PMMFDUJPO͕୲౰ ίϨΫγϣϯ੍͕‫͢ޚ‬ΔϝϦοτ ⾣ ΠϯσοΫεͷൣғ͸ίϨΫγϣϯ͕೺Ѳ͍ͯ͠Δ ⾣ ී௨ͷ‫ܕ‬ΛΠϯσοΫεͱͯ͠࢖͑Δ ໊฽‫ܕ‬ Kudo 開始インデックス index(before: "Kudo") Kumagai index(after: "Kumagai") Sato index(after: "Sato") Tanaka 終端インデックス

44.

ΠϯσοΫε੍‫ޚ‬͸$PMMFDUJPO͕୲౰ Ҡಈ΍‫཭ڑ‬΋ίϨΫγϣϯ͕୲౰ ⾣ BEWBODFE΍EJTUBODF͸ίϨΫγϣϯʹ࣮૷ ⾣ ΠϯσοΫεࣗମʹ͸‫ݪ‬ଇɺ࣮૷͞Εͳ͍ // 指定した距離だけ先のインデックスを取得 items.startIndex.advancedBy(5) items.index(items.startIndex, offsetBy: 5) // インデックス間の距離を取得 items.startIndex.distanceTo(items.endIndex) items.distance(from: items.startIndex, to: items.endIndex)

45.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ !OPFTDBQFΫϩʔδϟʔ

46.

!OPFTDBQFΫϩʔδϟʔ Ϋϩʔδϟʔͱ͸ ⾣ ଈ੮Ͱ࡞ΕΔແ໊ؔ਺ ⾣ पғͷม਺ΛऔΓࠐΜͰ࢖͑Δ var currentValue = 0 let closure = { () -> Int in currentValue += 1 内側で、外の変数をそのまま使える return currentValue }

47.

!OPFTDBQFΫϩʔδϟʔ Ϋϩʔδϟʔͷ‫ط‬ఆͷੑ࣭มߋ ⾣ 4XJGUͰ͸!FTDBQJOH͕‫ط‬ఆͷಈ࡞ͩͬͨ ⾣ 4XJGU͔Β!OPFTDBQF͕‫ط‬ఆʹͳΔ // 明記がないものは、非エスケープなクロージャー func doSomething(predicate: () -> Int) { } // エスケープ可能にしたい場合は、明記が必要に func doSomething(predicate: @escaping () -> Int) { }

48.
[beta]
!OPFTDBQFΫϩʔδϟʔ

&TDBQJOHΫϩʔδϟʔʢ4XJGUͷ‫ط‬ఆʣ
⾣ ม਺΍໭Γ஋Ͱɺࣗ༝ʹ֎΁࣋ͪग़ͤΔ
⾣ ಺෦ʹऔΓࠐΜͩม਺ͷੜଘൣғ͕֦ு͞ΕΔ

func transfer(content: Data,
completionHandler: @escaping () -> Void) {
// 非同期処理など、別のスコープへ渡せる

DispatchQueue.main.async {
completionHandler()
}
}

49.
[beta]
!OPFTDBQFΫϩʔδϟʔ

/PO&TDBQFΫϩʔδϟʔʢ4XJGUͷ‫ط‬ఆʣ
⾣ ม਺΍໭Γ஋Ͱɺ֎ʹ࣋ͪӡ΂ͳ͍
⾣ ఆٛͨ͠είʔϓ֎Ͱ͸࢖͑ͳ͍͜ͱ͕໿ଋ͞ΕΔ

func transfer(content: Data,
completionHandler: () -> Void) {
// 非同期処理など、別のスコープへ持ち出せない

DispatchQueue.main.async {
completionHandler()
}
}

$MPTVSFVTFPGOPOFTDBQJOHQBSBNFUFS
bDPNQMFUJPO)BOEMFS`NBZBMMPXJUUPFTDBQF

50.
[beta]
!OPFTDBQFΫϩʔδϟʔ

/PO&TDBQFΫϩʔδϟʔͷར఺
⾣ ୈࡾऀʹอ࣋͞Εͳ͍͜ͱ͕໿ଋ͞ΕΔ

w Ή͠Ζɺؔ਺ࣗ਎͕อ࣋͠ͳ͍͜ͱΛओுͰ͖Δ
w ؒҧͬͯͲ͔͜΁อ࣋ͯ͠͠·͏ͷΛ༧๷Ͱ͖Δ

⾣ ͲΜͳม਺Λғ͍ࠐΜͰ΋ ॥‫ࢀ؀‬র͕‫͜ى‬Βͳ͍

// たとえ、素性の知れない関数であっても …

func callBlackBox(predicate: () -> Int)
// @noescape なら循環参照の心配はない

callBlackBox {
return self.items.count
}

51.

!OPFTDBQFΫϩʔδϟʔ /PO&TDBQFΫϩʔδϟʔͷੑ࣭ !OPFTDBQFͰ ΫϩʔδϟʔΛड͚औΔؔ਺ ؔ਺είʔϓ 変数 ғ͍ࠐΈ クロージャー 変数 !OPFTDBQF౉͠ Non-Escape クロージャー ֎ʹ͸࣋ͪग़͞Εͳ͍ !OPFTDBQFͳΒ ౉ͨ͠ઌͰ ઈରʹ࢖͍ऴΘΔ 変数 Ϋϩʔδϟʔͱม਺͸ ໾໨ऴྃ

52.

!OPFTDBQFΫϩʔδϟʔ &TDBQJOHΫϩʔδϟʔͷੑ࣭ !FTDBQJOHͰ ΫϩʔδϟʔΛड͚औΔؔ਺ ؔ਺είʔϓ 変数 ғ͍ࠐΈ クロージャー 変数 !FTDBQJOH౉͠ Escaping クロージャー ֎ͷม਺ʹอ࣋͞ΕΔ͔΋ !FTDBQJOHͩͱ౉ͨ͠ઌͰ ࢖͍ऴΘΔͱ͸ ‫ݶ‬Βͳ͍ 変数 Ϋϩʔδϟʔͱม਺͸ ҡ࣋͞ΕΔ͔΋

53.

!OPFTDBQFΫϩʔδϟʔ &TDBQJOH͸॥‫ࢀ؀‬রʹ஫ҙ ؔ਺είʔϓ ΦϒδΣΫτ obj: Object ғ͍ࠐΈ クロージャー obj !FTDBQJOHͰ ΫϩʔδϟʔΛड͚औΔϝιου Escaping クロージャー ϓϩύςΟʔʹอ࣋ ॥‫ࢀ؀‬র プロパティー ॥‫ࢀ؀‬রͰPCK͕ղ์͞Εͳ͍

54.
[beta]
!OPFTDBQFΫϩʔδϟʔ

&TDBQJOHʹΑΔ॥‫ࢀ؀‬রͷྫ
class Object {
var completion: (() -> Void)?
func request(completion f: @escaping ()->Void) {
…; completion = f
}
}
let obj = Object()
// 循環参照を起こすか、外からはわかりづらい

obj.request {
print(obj)
}

55.

4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ ද໘͔Β‫͜ͱ͍͘ʹ͑ݟ‬ΖΛத৺ʹ঺հ

56.

&OKPZ4XJGU 5IBOLZPV 4XJGUͰ৽͘͠ͳͬͨͱ͜Ζ &;/&5‫۽‬୩༑޺ IUUQF[OFUKQ ⾣ 4XJGUͷίϯηϓτ ⾣ "1*໋໊‫ن‬ଇͷओͳͱ͜Ζ ⾣ *NQMJDJUMZ6OXSBQQFE0QUJPOBM ⾣ 4FRVFODFͷ৽‫ػ‬ೳ ⾣ ΠϯσοΫε͸$PMMFDUJPO੍͕‫ޚ‬ ⾣ !OPFTDBQFΫϩʔδϟʔ