autoreleasepoolから例外を投げられるようにする

Wednesday, February 10, 2016

最近ニッチな事しか投稿していない気がする。
何かおしゃれなUIが実現できるライブラリ!の方がウケが良いんだろうけれども..。

ライブラリの開発中に、

  • autoreleasepoolを使って、局所的にメモリの消費が増える部分を抑えたい
  • しかしautoreleasepoolの内部で例外を扱う箇所がある
  • autoreleasepool内で投げる例外を、autoreleasepoolの外に伝搬させて、外で処理をしたい

という問題に直面したのですが、

do {
    autoreleasepool {
        try ~~~~~ // ★
    }  
} catch (let e) {
    print(e) // ★の例外をここで処理したい
}

こうしたくても、autoreleasepoolに、throwsもしくはrethrowsが指定されていないので、これができません。 なので、

try autoreleasepool {
    try ~~~~~ // ★
}  

こんな感じでautoreleasepool内部の例外を伝搬させられるようにします。

public func autoreleasepool(@noescape code: () throws -> ()) rethrows {
    try {
        var error: ErrorType?
        autoreleasepool {
            do {
                try code()
            } catch (let e) {
                error = e
            }
        }
        if let error = error {
            throw error
        }
    }()
}

こんな感じで宣言してあげれば、

do {
    try autoreleasepool {
        try ~~~~~ // ★
    }  
} catch (let e) {
    print(e) // ★の例外をここで処理する
}

これができるようになります!やった!
Gistにも一応のこしておきます。

techSwiftiOStips

ライブラリ「PDFGenerator」をアップデートしました

Swiftのdo〜try〜catchとdeferの組み合わせ