Optional型
Optional型は、nilが入ることを許容する型のことである。
let year: Int? = 2020 //オプショナル型(Optional)
var event: String! = "東京オリンピック" //暗黙的アンラップオプショナル型(Implicitly Unwrapped Optional)
print(year) // => Optional(2020)
print(event)// => Optional("東京オリンピック")
//2つのアンラップ手法
//1 Forced Unwrapping:強制的にアンラップする
print(year!) // => 2020
//2 Optional Binding:nilかどうかを判定しアンラップする
guard let unwrappedYear1 = year else {return}
print(unwrappedYear1)// => 2020
//if let unwrappedYear1 = year {print(unwrappedYear1)}else{return}//上記と同義
//プロパティやメソッドを安全に取得
// Optional Chaining:オプショナル型の変数のプロパティやメソッドをオプショナル型で取り出す
var human: Human? = Human()
human?.name // => "Optional(山田太郎)"
human?.hello()// => nil
guard
≒if 条件に一致しなかった場合に、必ず処理を中断させるための構文。
func guardTest(status: Int) {
guard status == 0 else { return } // 引数が0でなかったらreturn
print("guardしない")
}
enum
列挙型。指定した型の値を割り当てたり(raw value enum)、要素に付属する値を定義したり(associated value)、入れ子構造にもできる(nested types)。
enum Character {
enum Weapon {
case bow
case sword
case lance
case dagger
}
enum Helmet {
case wooden
case iron
case diamond
}
case thief(weapon: Weapon, helmet: Helmet)
case warrior(weapon: Weapon, helmet: Helmet)
case knight(weapon: Weapon, helmet: Helmet)
}
let knight = Character.knight(weapon: .sword, helmet: .diamond)
mutating func
struct,enumで自身の値を変更する場合、mutatingが必要になる。
struct MyStruct {
var member: Int
init(member: Int){
self.member = member
}
mutating func plusOne() {
self.member += 1
}
}
var myStruct = MyStruct(member: 1)
myStruct.plusOne()
delegate
あるクラス(f)から他のクラス(x1)に処理を任せるというデザインパターン。
あるプロトコル(X)を継承した子クラス(x1,x2,x3)を、同様のプロトコル(X)をコンポジションしているクラス(f)のプロパティにセットできることを利用している。
イメージとしては、f(X)を定義しておけばf(x1)やf(x2),f(x3)にも利用でき、x1での演算はx1に委譲する。
f =X÷2
X =□+□+□
x1=1+1+1
x2=2+2+2
x3=3+3+3
1. 簡単な例
protocol Ask {//頼み
func goOtsukai()//頼むこと(お使いに行け!)
}
class Parent {
weak var delegate: Ask!//頼みを持っている
func say() {
print("おーい、お使い行ってきてー")
delegate.goOtsukai()
}
}
class Child1: Ask { //Parentに頼まれた依頼を承認している。
func goOtsukai() {
print("行ってまいります、母上!")
}
}
class Child2: Ask { //Parentに頼まれた依頼を承認している。
func goOtsukai() {
print("行ってまいります、母上!")
}
}
let myParent = Parent()
let myChild1 = Child1()
myParent.delegate = myChild1 //お使いに行ってもらう子供をChild1に指定。
myParent.say() //お使いを頼む
2. よくある実装例
"class ViewController"が"protocol SampleViewDelegate"を継承し、"class SampleView"のインスタンス"view"のデリゲートインスタンス"view.delegate"にselfをセットする。
class ViewController: UIViewController,SampleViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let view = SampleView(frame: CGRectMake(100,100,100,100))
// SampleViewがインスタンス化されたタイミングでデリゲートインスタンスにselfをセット
view.delegate = self
self.view.addSubview(view)
}
// SampleView DelegateMethod
// SampleViewのBackgroundColorが変更された事を通知
func didChangeBackgroundColor(str:String) {
print(str);
}
}
import UIKit
// SampleViewDelegate プロトコルを記述
@objc protocol SampleViewDelegate {
// デリゲートメソッド定義
func didChangeBackgroundColor(str:String)
}
class SampleView: UIView {
//SampleViewDelegateのインスタンスを宣言
weak var delegate: SampleViewDelegate?
override func drawRect(rect: CGRect) {
let button = UIButton()
button.setTitle("Tap", forState: .Normal)
button.frame = CGRectMake(0, 0, 50, 50)
button.backgroundColor = UIColor.redColor()
button.addTarget(self, action: "tappedButton:", forControlEvents:.TouchUpInside)
self.addSubview(button)
self.backgroundColor = UIColor.blackColor()
}
@IBAction func tappedButton(sender: AnyObject) {
self.backgroundColor = UIColor.greenColor()
// デリゲートメソッドを呼ぶ(処理をデリゲートインスタンスに委譲する)
self.delegate?.didChangeBackgroundColor("グリーン")
}
}
final class
このクラス以降、継承されることがない最後のクラス。
finalでサブクラスがないことを明示し、privateなどでアクセスレベルを限定すると動的ディスパッチ(Dynamic Dispatch)の可能性を減らせ、パフォーマンスの良いプログラムを作成できる。
class Animal { }
final class Dog: Animal { }
class Chihuahua: Dog { } // Dogのサブクラスは作成できない
循環参照
参照カウンタが0になり得ない状態を作ってしまう参照のこと。
weak
弱参照
引数のクロージャの属性
@escaping 属性
@autoclosure 属性
fileprivate
アクセス修飾子の一種。
private(スコープ内) < fileprivate(ファイル内) < internal(モジュール内) < public(別モジュールでも,継承不可) < open(別モジュールも,継承可能)
モジュール
≒フレームワーク(UIKit,AVFoundation etc)。すでにコンパイルされ、importで情報を取り込んで利用できるプログラムの集まり。
クラスメソッド
メソッドにはクラスメソッド、インスタンスメソッド、イニシャライザ(init)3種類ある。
クラスメソッドは、クラス名.クラスメソッド名と記述する。
class Human {
#1. クラスメソッドの定義はfuncの前に`class`が付く
class func helloClass() {
println("hello class")
}
}
#2. クラスメソッドの呼び出しは、クラス名.クラスメソッド名
Human.helloClass() //=> "hello class"
型名.self
型そのものは「型名.self」で取得できる。それを Any.Type型 の変数に代入できる。
let type:Any.Type = MyStruct.self
"."から始まる場合
列挙子の省略形
var imageView = UIImageView()
imageView.contentMode = .ScaleAspectFit
Type Cast Operator(as as! as?)
as :アップキャスト時。
as!:強制ダウンキャスト。
as?:ダウンキャスト時。オプショナル型を返す。
class Animal {}
class Dog: Animal {}
let dog = Dog()
let animal = dog as Animal // アップキャスト
let animal1: Animal = Dog()
let dog = animal1 as! Dog // OK
let animal1: Animal = Dog()
let dog = animal1 as? Dog // dogの型はOptional<Dog>
typealias
関数の別名を付ける事もでき、メソッドの引数部分がすっきりする。
typealias MyBlock = () -> ()
func method(block: MyBlock) {
block()
}
クロージャ
自己完結無名関数(型変数)。
クロージャ≒関数。
//クロージャ宣言
var intParamClosure: (Int,Int) -> Int
//クロージャ処理実装
intParamClosure = {
p1,p2 -> Int in
return p1 + p2
}
println(intParamClosure(3,5))
inの意味
func say(s:String)->() {
// body
}
{
(s:String)->() in // ←bodyの始まりを表すin
// body
}