狠狠撸

狠狠撸Share a Scribd company logo
Swi$%Protocol%and%Selector
2016/02/06
@TachibanaKaoru
自己紹介
渋谷のVOYAGE'GROUPでiOSエンジニア
をしています。
Twi$er:(@TachibanaKaoru
Blog(:(h$p://www.toyship.org/
朝時間jpというアプリをだしてます。
try!%Swi)
? h#p://tryswi-conf.com/
? 2016/3/293/4
? 痴翱驰础骋贰础骋搁翱鲍笔は迟谤测!础厂飞颈-のスポンサーをしています。
iOS$Developers$Conference$2016
*"h$ps://iosdc.jp
*"2016/08/20
*"@iosdcjp
Swi$%Protocol%Extension
Swi$%2.0から導入された機能。いままでインターフェース定義と
してしか使えなかったProtocolの実装部分も共通化できるように
なりました。
デバッグ出力を共通化してみる例
? こんなデバッグ出力用のプロトコルを作ったとします。
protocol DebugLog {
func writeDebugMessage() -> Void
}
デバッグ出力を共通化してみる例
? Swi%1.0ではこのプロトコルに適合しているクラスで実装を書
く必要がありました。
class ElmViewController : UIViewController, DebugLog {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
writeDebugMessage()
}
func writeDebugMessage() -> Void{
print("デバッグ出力の実装をここでする")
}
}
デバッグ出力を共通化してみる例
? Swi%&2.0では、プロトコル側にデフォルトの実装をかくことが
できます。
protocol DebugLog {
func writeDebugMessage() -> Void
}
extension DebugLog {
func writeDebugMessage() -> Void{
print("Protocol extensionで共通化されたデバッグ出力です。")
}
}
デバッグ出力を共通化してみる例
? Swi%2.0ではこのプロトコルに適合すれば実装を書く必要がな
くなりました。
class ElmViewController : UIViewController, DebugLog {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
writeDebugMessage()
}
// 書かなくていい
// func writeDebugMessage() -> Void{
// print("デバッグ出力の実装をここでする")
// }
}
デバッグ出力を共通化してみる例
? では、もし、Swi%2.0で処理が共通化されているプロトコルに
ついて、自分のクラスで実装を書いたらどうなるでしょうか。
? 自分のクラスの実装コードが実行されます
class ElmViewController : UIViewController, DebugLog {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
writeDebugMessage()
}
func writeDebugMessage() -> Void{
print("デバッグ出力の実装をここでする")
}
}
Swi$%2.0%Protocol%Extension
? プロトコル側に共通実装をもたせることで、実装を共通化でき
るが、上書きすることでクラスごとの独自処理にすることもで
きる
Swi$%2.0%Protocol%Extension
? protocolを適合しているクラスによって実装を変更したりも可
能
protocol DebugLog {
func writeDebugMessage() -> Void
}
extension DebugLog {
func writeDebugMessage() -> Void{
print("Protocol extensionで共通化されたデバッグ出力です。")
}
}
extension DebugLog where Self : UIViewController{
func writeDebugMessage() -> Void{
print("Protocol extensionで共通化されたデバッグ出力です。(ただし、selfがUIViewControllerです)")
}
}
プロトコルで実装したものをSelectorとしてよんでみる
? 下記のように、自分で実装しているProtocolをselectorでよびだ
す。>実行される
class ElmViewController : UIViewController, DebugLog {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
performSelector("writeDebugMessage")
}
func writeDebugMessage() -> Void{
print("デバッグ出力の実装をここでする")
}
}
プロトコルで実装したものをSelectorとしてよんでみる
? 下記のように、2.0のProtocol+extensionをselectorでよびだして
みましょう
class ElmViewController : UIViewController, DebugLog {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
performSelector("writeDebugMessage")
}
}
プロトコルで実装したものをSelectorとしてよんでみる
? 下記のように、2.0のProtocol+extensionをselectorでよびだす。
? 実行時エラーとなります
[Forest.ElmViewController writeDebugMessage]: unrecognized selector sent to instance
Protocol'Extensionで実装したメソッドは
Selectorとして指定することができない
? Apple&Developer&Forumでもまったく同じ話題がでていました。
? Func0on&in&Swi4&2&protocol&extension&returns&unrecognized&
selector&when&using&a&UIGestureRecognizer&to&call&it.
? hCps://forums.developer.apple.com/thread/16773
Selectorで指定できないとなにが困るのか。
例えば、UIBu%onのAc*onや、NSTimerやGestureのAc*onなど、
UIKitの主要機能のAc*onの指定をすることができない。

More Related Content

Swift Protocol and Selector