【Swift】 既存クラスにstored propertiesを追加する

アプリを作っていて、「既存のクラスをカスタマイズして、オリジナルの変数を付けたいなぁ」ってコト、あると思います。
少なくとも私はあります。

が、バカ正直に`extension`してvarで宣言すると以下のようなエラーで怒られます。

<img width="700" alt="スクリーンショット 2019-10-16 17.02.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/7f308ce0-5e86-d775-37b0-68b2b6aa43fc.png">

で、どうにかできないものかと。
そのクラスを継承したクラスを作ればいいんですよ、というブログエントリや質問サイトの回答も見たんですが、一応やりたいと思ったコトがやりたいと思った通りにできるのかどうか、確認しました。

結論としては、「__可能__」でした。

以下、サンプルです。

####ソースコード

```swift:Sample.swift

import UIKit

class ViewController: UIViewController {

    // このUILabelにプロパティを追加します。
    let testLabel = UILabel()

    let testButton = UIButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        testLabel.addedString = "プロパティ追加、成功！"
        testLabel.textColor = .black
        
        testButton.setTitle("tap me!",
                            for: .normal)
        testButton.frame = CGRect(x: 0,
                                  y: 0,
                                  width: 0,
                                  height: 0)
        testButton.sizeToFit()
        testButton.center = view.center
        testButton.setTitleColor(.blue,
                                 for: .normal)
        testButton.addTarget(self,
                             action: #selector(displayTest),
                             for: .touchUpInside)
        
        view.addSubview(testButton)
    }
    
    @objc func displayTest() {
        // 追加したプロパティから.textにセットして表示します。
        testLabel.text = testLabel.addedString
        testLabel.font = .systemFont(ofSize: 30)
        testLabel.textAlignment = .center
        testLabel.frame = CGRect(x: 0,
                                 y: 100,
                                 width: UIScreen.main.bounds.width,
                                 height: 50)
        view.addSubview(testLabel)
    }


}

// UILabelにプロパティ追加するextension
extension UILabel {
    private struct additional {
        static var addedString: String = ""
    }
    
    var addedString: String {
        get {
            guard let theName = objc_getAssociatedObject(self, &additional.addedString) as? String else {
                return ""
            }
            return theName
        }
        set {
            objc_setAssociatedObject(self, &additional.addedString, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}


```

####画面イメージ
|ボタン押下前|
|:-:|
|<img width="400" alt="Simulator Screen Shot - iPad Air 2 - 2019-10-16 at 16.55.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/158bfac9-20f5-0380-132e-e5bf552d6e67.png">|

|ボタン押下前|
|:-:|
|<img width="400" alt="Simulator Screen Shot - iPad Air 2 - 2019-10-16 at 16.55.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/b28fb4a1-99d7-06bc-31df-601f4ae4015c.png">|

viewDidLoad()で追加したプロパティ（addedString）にセットした値が、ボタン押下時にtextにセットされ、画面に表示できています。


####参考
stackoverflowの下記QAが参考になりました。
[“Extensions may not contain stored properties” unless your are Apple? What am I missing? - stackoverflow](https://stackoverflow.com/questions/44674549/extensions-may-not-contain-stored-properties-unless-your-are-apple-what-am-i)

以上です〜