Swift3.0でautoreleasepool
が強化されたようなので。
はじめに
Swift3.0-preview1時点でのお話となります。
Swift3時代のautoreleasepool
Swift3時代のautoreleasepool
では、いままでできなかった2つのことが可能になります。
- 値を返却することができる
- エラーハンドリングができる
それぞれ順に見ていきます
その前に
autoreleasepool
は以下のように宣言されています。
public func autoreleasepool<Result>(_ body: @noescape () throws -> Result) rethrows -> Result
Generics 、 @noescape 、 throws,rethrows が使われています。
ちなみに、Swift2時代までは、
public func autoreleasepool(@noescape code: () -> Void)
でした。@noescape
しか目立った特徴がなかったです。
値を返却することができる
今までは、autoreleasepool
内で何か操作をして値が欲しい場合には、外にvar
で変数を用意して、代入する必要がありました。
var hoge: String?
autoreleasepool {
// do something
hoge = "hoge"
}
print(hoge) // => Optional("hoge")
これが、Swift3になると…
var hoge: String = autoreleasepool {
// do something
return "hoge"
}
print(hoge) // => "hoge"
と、 スッキリ 書くことができます。
Generics による型推論が働くので、
var hoge = autoreleasepool {
// do something
return "hoge"
}
と、変数の型を省略することもできます。
エラーハンドリングができる
個人的にはこちらの方が嬉しかったです。
これができなくて、Swift2時代では自前でautoreleasepool
をオーバーロードして用意していました。
さらに、rethows が付いているため、 closure 内でエラーハンドリングがなければ、autoreleasepoolの外側で一々エラーハンドリングをする必要がなく、通常通り使えることも特徴です。
// 画像を指定したfileURLに保存する
enum CustomError: ErrorProtocol {
case convertFailed
}
func saveToLocal(_ image: UIImage?, url: URL) throws {
try autoreleasepool {
guard let image = image, data = UIImagePNGRepresentation(image) else {
throw CustomError.convertFailed
}
try data.write(to: url, options: .dataWritingAtomic)
}
}
// ...
do {
try saveToLocal(image, url: fileURL)
} catch let error {
print(error)
}
メモリ消費を抑えるためにautoreleasepool
を使って、その内部で例外があれば throw して早めに抜けたい時に便利になりますね。
ちなみに、僕が作っているライブラリでもこれを活用しています。
さいごに
是非、パワーアップしたautoreleasepool
を使ってあげてください!