LoginSignup
6
5

More than 5 years have passed since last update.

Swift3でDataをNSDataにブリッジさせて使うとクラッシュする事がある

Posted at

再現コード

タップされたら、適当なイメージを作ってPNGのDataを生成し、それをファイルに保存するだけのコードです。
DataNSDataにキャストしてwrite(toFile:atomically:)を呼び出すとクラッシュします。

(iOS8.4で確認。iOS10では再現せず。)

ViewController.swift
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        let path = (documentDirectory as NSString).appendingPathComponent("test.dat")

        UIGraphicsBeginImageContext(CGSize(width: 100, height: 100))
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        if let img = img, let data = UIImagePNGRepresentation(img) {
            if (data as NSData).write(toFile: path, atomically: false) {
                print("保存しました。")
            }
        }
    }
}

エラー箇所

スクリーンショット 2016-09-30 18.02.29.png

回避方法

普通にData型の方の書き出し機能を使えば良さそうです。

ただ、使い勝手があまり良くなかったのでextensionしました。

extension Data {
    @discardableResult
    func write(toFile: String, atomically: Bool) -> Bool {
        return (try? self.write(to: URL(fileURLWithPath: toFile), options: atomically ? .atomic : [])) != nil
    }
}

これでブリッジさせなくとも、write(toFile:atomically:)が呼べますし、クラッシュもしなくなります。

最後に

急いで書いたので間違いがあったらすみません。
何故不正終了するのかなど、ご存知の方がいらっしゃいましたら情報を頂けると助かります。

6
5
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
6
5