Visual Studio 2019 for Mac version 8.0 Preview 5 がリリースされました。
今回のリリースは、基本的にはバグフィックスで、新たな機能の追加はないようです。
修正内容も、致命的なものではなく細かいバグフィックスになってきましたので、いよいよ正式版リリースの準備が整ってきましたね。
詳細な修正内容につきましては公式サイトをご覧ください。
私も早速アップデートし、色々確認しています。
正式版のリリースが待ち遠しいですね!
Visual Studio 2019 for Mac version 8.0 Preview 5 がリリースされました。
今回のリリースは、基本的にはバグフィックスで、新たな機能の追加はないようです。
修正内容も、致命的なものではなく細かいバグフィックスになってきましたので、いよいよ正式版リリースの準備が整ってきましたね。
詳細な修正内容につきましては公式サイトをご覧ください。
私も早速アップデートし、色々確認しています。
正式版のリリースが待ち遠しいですね!
Visual Studio 2019 for Mac version 8.0 Preview 4 がリリースされました。
今回のリリースは、基本的にはバグフィックスで、新たな機能の追加はないようです。その中でも、インストーラーにはかなり修正が入りました。
インストーラー修正内容は以下の通りです。
また、 Android Emulator に関する問題も修正されています。
その他、細かい修正内容につきましては公式サイトをご覧ください。
私も早速アップデートし、色々確認しています。
正式版のリリースが待ち遠しいですね!
Visual Studio for Mac をご愛用の皆さまお待たせしました!
Windows では、 Visual Studio 2019 RC がリリースされましたが、Mac でも Visual Studio 2019 for Mac version 8.0 Preview 3 がリリースされました。
目玉機能は以下の通りです。
私も早速インストールし、色々機能を試しています。
今後、Visual Studio for Mac も Windows 版と機能差が少なくなっていくといいですね!
前回の記事で、Wrapper Types と User Types について説明しましたが、言葉だけだとわかりにくいので、図を交えて補足したいと思います。
hiro128.hatenablog.jp
Wrapper types は、UIView や UIButton のような Objective-C の組み込み型をラップしたもので、マネージドの世界では、ネイティブオブジェクトのインスタンスへのハンドルだけを持っています。
User types は、UIView や UIButton のような Wrapper types を継承し派生した型で、Objective-C に対応する型が無いものを指し、ネイティブオブジェクトのインスタンスへのハンドルの他に、マネージドな世界だけで管理されている、フィールド、プロパティやメソッドを持っています。
public class MyView : UIView { string myField; public string MyProperty { get; set; } public MyView(string fieldValue) { myField = fieldValue; } } var view = new MyView("fieldValue") { MyProperty = "propertyValue" };
これで、Wrapper Types と User Types の違いがわかりやすくなりましたら幸いです。
今回は以上です。
こんにちは、@hiro128_777です。
この記事は「Xamarin その1 Advent Calendar 2018」の21日目になります。
Xamarin.iOS は基本的には、Objective-C の薄い Wrapper であることは間違いありませんが、オブジェクトがマネージドの世界とネイティブの世界でそれぞれに存在し、互いに関係性を持ちながら、インスタンスが生成・破棄されているので、GC の挙動を正しく理解しておかないとメモリリークをコントロールするのが難しくなる弱点があります。今回はそこについてのお話です。
この記事の内容については Xamarin.iOS のソースコードhttps://github.com/xamarin/xamarin-macios/blob/master/runtime/runtime.mに記載されています。
これは、Xamarin.iOS の GC の挙動について調べるために、Xamarin.iOS のソースコード を読んでいるときに偶然発見しました。これを読むと Xamarin.iOS の GC の挙動のクセがわかると思います。
このような超重要な事が、そんなところに書いてあってもなかなか皆さんが目にする機会はないと思い、今回日本語に翻訳し説明を追加しました。
※わかりやすくするために色々補完して翻訳していますので、原文に忠実な翻訳ではありません。
GC の挙動にかかわる iOS アプリののアーキテクチャーについてはこちらの公式ドキュメントもご参照いただくとより理解が深まります。
docs.microsoft.com
また、より詳しい記事を書き始めましたのでこちらもご覧ください。
hiro128.hatenablog.jp
Wrapper type は、UIView
や UIButton
のような Objective-C の組み込み型をラップしたもので、マネージドの世界では、ネイティブオブジェクトのインスタンスへのハンドルだけを持っています。
一方、User type は、UIView
や UIButton
のような Wrapper type を継承し派生した型で、Objective-C に対応する型が無いものを指し、ネイティブオブジェクトのインスタンスへのハンドルの他に、マネージドな世界だけで管理されている、フィールド、プロパティやメソッドを持っています。
Xamarin.iOS における GC の挙動を考える上で、この2つの型の区別はとても重要となります。
これはとても簡単です。
Wrapper type のインスタンスの寿命は、ネイティブオブジェクトの寿命とはリンクしてません。
Wrapper type のインスタンスは、マネージドな世界にネイティブオブジェクトへのハンドル以外には何も保持していませんので、GC の判断によっていつでも自由に解放できます。もし、後の段階で再びそのオブジェクトが必要になった場合には Wrapper type のインスタンスが再度作成されるだけです。
こちらは簡単ではありません。
User type のオブジェクトは マネージドな世界にユーザーが定義した状態を含む可能性があるため GC の判断によって自由に解放することはできません。
よって、User type のオブジェクトを必要な間はずっと生かし続けることを保証する必要があります(マネージオブジェクトは強力な GCHandle によって保持されます)。
この場合の問題は「どうやって不要になったタイミングを判断するのか」ということになります。
これには、歴史的に2つのケースが存在します。
ユーザーが Dispose を呼び出すと、マネージオブジェクトの参照が解放され、ネイティブオブジェクトとマネージオブジェクトの間のリンクが切断され、GC がそのオブジェクトを解放できるようになります。(そのマネージオブジェクトを保持している他のオブジェクトが何もなければ)
参照カウンタが1に達すると、マネージオブジェクトからの参照が唯一の参照であり、ネイティブコードは当該オブジェクトを再び使用しないと安全に仮定できます。よって、リンクを解除し、ネイティブオブジェクトを解放して、GC がマネージオブジェクトを解放できるようにします。
ケース1で、ユーザーが Dispose を呼び出した後、ネイティブコードが何らかの理由でそのオブジェクトを使用しようとすると、問題が発生します。 Xamarin.iOS は対応するマネージオブジェクトが存在しないことを検出し、それを(再)作成しようとします。ですが、これは失敗し、プロセスを終了させる例外がスローされます(この時、スタックにはマネージドフレーム/例外ハンドラが存在しない可能性があります)。
解決策としては、Disposeを呼び出すときに、次のことを行う必要があります。
これにより、ネイティブオブジェクトが存続している限り、マネージオブジェクトを引き続き参照することができます。
(それ以外の時は、マネージオブジェクトに強力な GCHandle があるため、GC の解放処理はブロックされます。)
User type のオブジェクトはすでに GCHandle を保存する Objective-C インスタンス変数を持っているので、別のインスタンス変数を作成しません。
User type のオブジェクトはマネージオブジェクトへの参照(MANAGED_REF_BIT)があるかどうかを GCHandle の1ビットで保存します。
Wrapper type は単に、ラッパーですので難しいことは何もありません。
問題は、User type です。こちらは、マネージドな世界とネイティブの世界にそれぞれ状態を持つことになるので、GC の挙動が複雑になっています。
オブジェクトの解放がうまく行われない時には、今回の内容を確認してたいただくとヒントになると思います。実際私もこれを理解してからは、解放できなくて困ったり、強引な Dispose で Exception に悩まされることが無くなりました。
以上です。