LoginSignup
32
28

More than 5 years have passed since last update.

Swiftで既存のクラスに新たにプロパティを追加する方法

Last updated at Posted at 2014-08-31

Swiftで既存のクラスに新たにプロパティを追加する方法

Objective-Cでも使えていましたランタイムAPI(俗にいう黒魔術)を使う事で、Swiftでも動的にプロパティを追加することが可能です。

Runtime API Reference URL

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html

使用するランタイムAPIの関数

  • objc_setAssociatedObject(object: AnyObject!, key: CConstVoidPointer, value: AnyObject!, policy: objc_AssociationPolicy)

    引数で受け取ったオブジェクトに対して、動的に引数のプロパティをセットします

     

    【object : AnyObject!】

    動的にプロパティを追加したい対象オブジェクト

     

    【key : CConstVoidPointer】

    プロパティにアクセスするためのセレクタのポインタ、Objective-Cと違い文字列をポインタにするとクラッシュ します

     

    【policy : objc_AssociationPolicy】

    UIntに変換して指定することで属性を指定します

  • objc_getAssociatedObject(object: AnyObject!, key: CConstVoidPointer) -> AnyObject!

    引数で受け取ったオブジェクトから、動的に引数のプロパティを取得します

     

    【object: AnyObject!】

    動的にプロパティを取得したい対象オブジェクト

     

    【key : CConstVoidPointer】

    プロパティにアクセスするためのセレクタのポインタ、Objective-Cと違い文字列をポインタにするとクラッシュ します

objc_AssociationPolicyについて

上記でも説明しましたがobjc_AssociationPolicyはUInt型に変換する必要があります。その理由としては定義を見れば分かります。

typealias objc_AssociationPolicy = UInt

以下AssociationPolicyの種類

  • OBJC_ASSOCIATION_ASSIGN
  • OBJC_ASSOCIATION_RETAIN_NONATOMIC
  • OBJC_ASSOCIATION_COPY_NONATOMIC
  • OBJC_ASSOCIATION_RETAIN
  • OBJC_ASSOCIATION_COPY

使用例

AクラスのオブジェクトにStringのプロパティである「hoge」を動的に追加してみます

class A {

  var hogeSelector = Selector("hoge")

  // プロパティを動的にセットします
  func setHoge(hoge : String) {
    objc_setAssociatedObject(
      self,
      &hogeSelector,
      hoge,
      UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
  }

  // プロパティを動的に取得します
  func hoge()->String! {
    if let hoge = objc_getAssociatedObject(
      self,
      &hogeSelector
      ) as? String
    {
      return hoge
    }
    return nil
  }
}

動的に追加したプロパティにアクセスします

var a = A()
a.setHoge("swift")
println( a.hoge() ) //-> swift

おわりに

SwiftでもObjective-Cと全く同じランタイムAPIが用意されているため、他にもSwizzlingやClosureからのIMP生成などの処理も可能です。

本来設計がしっかりしていれば使う事はないですが、この柔軟性こそがSwift(Objective-C)の特徴ではないでしょうか。

32
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
28