Slide 1

Slide 1 text

第4回 Swift Study 〜~ Optionalについて詳しく知りたい 〜~

Slide 2

Slide 2 text

Optional ɾOptionalとは Optionals are an example of the fact that Swift is a type safe language.

Slide 3

Slide 3 text

Optional ɾSwiftでは通常の変数にnilを代⼊入できない   var intValue: Int = nil // コンパイルエラー ɾObjective-C  オブジェクトを参照するポインタが無い ! ɾSwift  存在しない値  

Slide 4

Slide 4 text

Optional ɾOptionalを指定すると変数にnilを代⼊入できる   var intValue: Int? = nil // OK これ  

Slide 5

Slide 5 text

Optional ɾʮT ?」って書くけど、実は「Optional」    var intValue: Int? = nil   // Optional !  var strValue: String? = nil   // Optional  var intValue: Optional = nil // Optional !  var strValue: Optional = nil // Optional ラップ(Wrap)されている

Slide 6

Slide 6 text

Optional ɾOptionalな変数は⾮非Optionalな変数と同じようには扱えない var int1: Int = 1 println(int1 + 2) // ->"3" ! ! var int2: Int? = 1 println(int2 + 2) // コンパイルエラー Optional    と    Int    ではそもそも型が違う

Slide 7

Slide 7 text

Optional ɾOptionalな変数を扱うにはアンラップ(Unwrap)する必要がある ˙アンラップ(Unwrap)                =  OptionalからTを取り出すこと

Slide 8

Slide 8 text

Unwrap ɾΞϯϥοϓ(Unwrap)するやり⽅方は複数あるらしい 1.Forced Unwrapping ! 2.Optional Chaining ! 3.Optional Binding ! 4.Implicitly Unwrapped Optional

Slide 9

Slide 9 text

Forced Unwrapping ɾʮ!」をつかってアンラップする⽅方法 class Team { func ios() -> String { return "nabe" } } var team: Team? = Team() println(team!.ios()) // アンラップ(!)できる -> "nabe" ! println(team.ios()) // コンパイルエラー(ラップされたままの状態では呼べない) ! team = nil println(team!.ios()) // アンラップ(!)する際にランタイムエラー 取り出している

Slide 10

Slide 10 text

Optional Chaining ɾʮ?」をつかってアンラップ class Team { func ios() -> String { return "nabe" } } var team: Team? = Team() println(team?.ios()) // アンラップできる -> "Optional("nabe")" ! team = nil println(team?.ios()) // アンラップ時にnilが返ってくる -> "nil" Optionalで取り出す

Slide 11

Slide 11 text

Optional Binding ɾif⽂文やwhile⽂文の条件で宣⾔言され、Optionalな変数を代⼊入された変数が、
  ⾮非Optional型になることを利⽤用してアンラップする class Team { func ios() -> String { return "nabe" } } var team: Team? = Team() ! if let unwrappedteam = team { println(unwrappedteam.ios()) // ->“nabe" } ! team = nil if let unwrappedteam = team { // ->false println(unwrappedteam.ios()) } unwrappedteamは⾮非Optionalになる

Slide 12

Slide 12 text

Implicitly Unwrapped Optional ɾOptional(Optional)ではなく、ImplicitlyUnwrappedOptionalを
  使って、暗黙的にアンラップする class Team { func ios() -> String { return "nabe" } } // 「?」ではなく「!」を使って宣⾔言 var team: Team! = Team() println(team.ios()) // 暗黙的にアンラップされる -> "nabe" ! team = nil println(team.ios()) // ランタイムエラーが発⽣生する

Slide 13

Slide 13 text

Implicitly Unwrapped Optional ɾʮUFBNʯ͸ ImplicitlyUnwrappedOptionalUFBNΛ
 ؆୯ʹॻ͍͚ͨͩͷ΋ͷ ちなみにɾɾɾɾ

Slide 14

Slide 14 text

まとめ ɾ*NQMJDJUMZ6OXSBQQFE0QUJPOBM ! ɾOJM͸୅ೖͰ͖Δ ɾ࢖༻͢Δͱ͖ʹ҉໧తʹΞϯϥοϓ͞ΕΔ ɾOJMʹରͯ͠Ξϯϥοϓ͢ΔͱɺϥϯλΠϜΤϥʔ͕ൃੜ͢Δ ɾ0QUJPOBM ! ɾOJM͸୅ೖͰ͖Δ ɾ࢖༻͢Δͱ͖͸໌ࣔతͳΞϯϥοϓ͕ඞཁ ɾOJMʹରͯ͠Ξϯϥοϓ͢ΔͱɺOJMͰฦ٫͞ΕΔ

Slide 15

Slide 15 text

いつ使うの? ࣮ࡍͷίʔσΟϯάͰ4XJGUͰ0QUJPOBMͷ͜ͱΛߟྀ͢ΔओͳγνϡΤʔγϣϯ ɾΫϥεͷϓϩύςΟ ! ɾؔ਺ͷฦΓ஋ ! ɾؔ਺ͷҾ਺ ͱ͔͕ɺߟ͑ΒΕΔɻ

Slide 16

Slide 16 text

クラスのプロパティ class Person { var name: String var age: Int = 30 // 宣⾔言時に初期化 var address: String init() { // init内で初期化 self.name = "" self.address = "Tokyo" } } ɾॳظ஋͕ܾ·͍ͬͯΔ৔߹͸ඇ0QUJPOBMͰఆٛ ! ɾએݴ࣌ʹॳظԽ͠ͳ͍৔߹ɺJOJU ͰॳظԽ͠ͳ͍ͱ࣮ߦͰ͖ͳ͍

Slide 17

Slide 17 text

クラスのプロパティ class SampleViewController: UIViewController { // サーバから取得した画像を保持する変数などは?にしておく var sampleImage: UIImage? override func viewDidLoad() { super.viewDidLoad() var url = NSURL(string: "http://example.png") var request = NSURLRequest(URL: url) NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in ! self.sampleImage = UIImage(data: data) } } } ɾॳظ஋͕ܾ·ͬͯͳ͍৔߹ͰɺॳظԽ͞Εͳ͍͔΋͠Εͳ͍ͱ͖͸
 ɹ0QUJPOBMͰએݴ͢Δ

Slide 18

Slide 18 text

クラスのプロパティ class SampleViewController: UIViewController { // nilにはしたくない。インスタンス⽣生成時には初期化できないので!を付ける var sampleView: UIView! override func viewDidLoad() { super.viewDidLoad() // 必ず初期化 self.sampleView = UIView(frame: self.view.frame) self.view.addSubview(self.sampleView) } } ɾॳظ஋͸ܾ·ͬͯͳ͍͕ɺඞͣॳظԽ͠ͳ͚Ε͹ͳΒͳ͍৔߹͸
 ɹ6OXSBQͰએݴ͢Δ

Slide 19

Slide 19 text

関数の返り値 ɾ6*5BCMF7JFXͩͱEFRVFVF3FVTBCMF$FMM8JUI*EFOUJGJFSͷฦΓ஋͕
 "OZ0CKFDU ͳͷͰ6*5BCMF7JFX ͰΩϟετɾɾ͍΍ɺ6*5BCMF7JFXʂ
 ɹͷ΄͏͕Մಡੑ͕ɾɾɾɾ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)          -> UITableViewCell   { // dequeueReusableCellWithIdentifierの返り値がAnyObject?なのでUITableViewCell?でキャスト var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell? if cell == nil { cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") } cell?.textLabel?.text = "Text" cell?.textLabel?.font = UIFont.systemFontOfSize(14.0) cell?.textLabel?.backgroundColor = UIColor.redColor() return cell! }

Slide 20

Slide 20 text

関数の返り値 ɾBT Λ͔ͭ͏ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell ! if cell == nil { cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") } ! cell?.textLabel?.text = "Text" cell?.textLabel?.font = UIFont.systemFontOfSize(14.0) cell?.textLabel?.backgroundColor = UIColor.redColor() ! return cell! }

Slide 21

Slide 21 text

関数の返り値 ɾ6*5BCMF7JFX$FMMͰड͚औΔ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell:UITableViewCell! = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell ! if cell == nil { cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") } ! cell.textLabel?.text = "Text" cell.textLabel?.font = UIFont.systemFontOfSize(14.0) cell.textLabel?.backgroundColor = UIColor.redColor() return cell }

Slide 22

Slide 22 text

関数の返り値 ɾ؆୯ʹݴ͏ͱ class Team { func ios() -> AnyObject? { return "nabe" } func and() -> AnyObject { return "fujiwarano" } func sdk() -> AnyObject! { return “icchi" } }

Slide 23

Slide 23 text

関数の返り値 ɾBT Λ༻͍ͯΩϟετͰ͖Δ͔֬ೝ var app: Team = Team() ! if let a = app.ios() as? String { println(a) // ->"nabe" } ! if let a = app.and() as? String { println(a) // ->"fujiwarano" } ! if let a = app.sdk() as? String { println(a) // ->"icchi" }

Slide 24

Slide 24 text

関数の返り値 ɾݒ೦ ɹ ɹɾຖճJGจ͖ͬͯνΣοΫ͢Δͷʁ ɹݱࡏ͸ͦΕ͕ҰൠతΒ͍͠ɻ ɹॻ͖ํΛ޻෉͠ͳ͍ͱJGจͰΧΦεʹͳΔ͔΋ɻ˞

Slide 25

Slide 25 text

関数の引数 ্ه͸ҧ͏ؔ਺ͱͯ͠ѻΘΕΔɻ class Test { func printNum(num : NSNumber) -> String { return "printNum A" } ! func printNum(num : NSNumber?) -> String { return "printNum B" } }

Slide 26

Slide 26 text

関数の引数 var test: Test = Test() ! test.printNum(NSNumber(int: 1)) // -> "printNum A" ! var value: NSNumber? = NSNumber(int: 1) ! test.printNum(value) // -> "printNum B" ! test.printNum(value!) // -> "printNum A" ! var value1: NSNumber? ! test.printNum(value1) // -> "printNum B" class Test { func printNum(num : NSNumber) -> String { return "printNum A" } ! func printNum(num : NSNumber?) -> String { return "printNum B" } }

Slide 27

Slide 27 text

関数の引数 ɾ৔߹ʹΑΓ·͢ɻʢέʔεόΠέʔεʣ ɹཧ༝ɿؔ਺ͷΦʔόʔϩʔυ͕Ͱ͖Δ͔Β

Slide 28

Slide 28 text

まとめ ! ɾ4XJGUͰ͸0QUJPOBMͱ͍͏֓೦͕ݴޠϨϕϧͰଘࡏ͢Δ͓ӄͰɺ
 ɹίϯύΠϥ͕ϩδοΫνΣοΫͯ͘͠ΕΔͱ͍͏ܕ҆શͳ໘͕͋Γɺ
 ɹݴޠͱͯ͠ྑ͍ײ͡ɻ ! ɾJ04ΤϯδχΞ͸0CKFDUJWF$ͰOJM΁ͷϝιουݺͼग़͕͠
 ɹແࢹ͞ΕΔͷͰɺͦͷล͋Μ·Γҙࣝͨ͜͠ͱ͕ͳ͔ͬͨɻ
 ɹͦͷͨΊɺ0QUJPOBMͷඞཁੑΛ͋·Γײͯ͡ͳ͍ɻ
 
 ɾ4XJGUͰ͸0QUJPOBM͸ආ͚ͯ͸௨Εͳ͍ɻ
 ɹҙࣝ͠ͳ͕Β࣮૷͠ͳ͍ͱΫϥογϡܥͷόά͕૿Ճ͢Δ͔΋ɻ

Slide 29

Slide 29 text

m(_ _)m