Unity+iOSでMemoryWarning発生時にSystem.GCとかResources.Unloadとかさせる

# Objective-CでMemoryWarningを受け取れるようにする
### ネイティブの処理を書けるようにする
まず、`Assets/Plugins/iOS/`以下に、`MyAppController.mm`ファイルを作成します。
`MyAppController`には`UnityAppController`を継承させます。
`IMPL_APP_CONTROLLER_SUBCLASS(MyAppController)`することで、`UnityAppController`の代わりに`MyAppController`が使われるようになります。

```objc
#import "UnityAppController.h"
@interface MyAppController : UnityAppController
@end
@implementation MyAppController
@end
IMPL_APP_CONTROLLER_SUBCLASS(MyAppController)
```
あとは、このMyAppControllerを改造すれば、何でも処理をいれられます。
### applicationDidReceiveMemoryWarningを実装する

```objc
#import "UnityAppController.h"

@interface MyAppController : UnityAppController
@end

@implementation MyAppController
- (void) applicationDidReceiveMemoryWarning:(UIApplication*)application
{
    [super applicationDidReceiveMemoryWarning:application];
    printf_console("メモリやばいよ\n");
}
@end

IMPL_APP_CONTROLLER_SUBCLASS(MyAppController)
```
こんな感じです。
シミュレータで`Hardware/Simulate Memory Warning`を実行してみて"メモリやばいよ"が見えれば成功です。

# Unity世界でMemoryWarningを受け取る窓口を作る
`MonoBehaviour`を継承して、MemoryWarningを受け取るコンポーネントを作ります。

```csharp
using UnityEngine;
public class MemoryWarningReciever : MonoBehaviour
{
    public void DidReceiveMemoryWarning (string message)
    {
        Debug.Log ("メモリやばいってよ:" + message);
        Debug.Log ("GCするよ");
        System.GC.Collect ();
        Debug.Log ("使ってなさそうなアセットを開放するよ");
        Resources.UnloadUnusedAssets ();
    }
}
```
これをシーン中のゲームオブジェクトにアタッチしておきます。
わかりやすく、ゲームオブジェクトの名前も`MemoryWarningReciever`にしておきましょう。

# ネイティブ世界からUnity世界へメッセージを送る
上で作っておいた`MyAppController`の`applicationDidReceiveMemoryWarning`関数から、`MemoryWarningReciever`をアタッチされたゲームオブジェクトにメッセージを送るために`UnitySendMessage`関数を使います。

```objc
- (void) applicationDidReceiveMemoryWarning:(UIApplication*)application
{
    [super applicationDidReceiveMemoryWarning:application];
    printf_console("メモリやばいよ\n");
    UnitySendMessage("MemoryWarningReciever", "DidReceiveMemoryWarning","");
}
```

`UnitySendMessage`関数の第一引数はオブジェクト名、第二引数が関数名です。

# 実行ログ
```
2015-02-01 04:52:23.109 ProductName[29257:223014] Received memory warning.
WARNING -> applicationDidReceiveMemoryWarning()
メモリやばいよ
メモリやばいってよ:
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
MemoryWarningReciever:DidReceiveMemoryWarning(String) (at /Users/hoge/moge/Assets/MemoryWarningReciever.cs:9)
 
(Filename: /Users/hoge/moge/Assets/MemoryWarningReciever.cs Line: 9)

GCするよ
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
MemoryWarningReciever:DidReceiveMemoryWarning(String) (at /Users/hoge/moge/Assets/MemoryWarningReciever.cs:10)
 
(Filename: /Users/hoge/moge/Assets/MemoryWarningReciever.cs Line: 10)

使ってなさそうなアセットを開放するよ
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
MemoryWarningReciever:DidReceiveMemoryWarning(String) (at /Users/hoge/moge/Assets/MemoryWarningReciever.cs:12)
 
(Filename: /Users/hoge/moge/Assets/MemoryWarningReciever.cs Line: 12)

System memory in use before: 1.0 MB.
Unloading 2 Unused Serialized files (Serialized files now loaded: 0 / Dirty serialized files: 0)
System memory in use after: 1.0 MB.

Unloading 1 unused Assets to reduce memory usage. Loaded Objects now: 102.
Total: 0.632223 ms (FindLiveObjects: 0.063613 ms CreateObjectMapping: 0.013408 ms MarkObjects: 0.159459 ms  DeleteObjects: 0.019284 ms)
```

-----
ただし、System.GCしても、リソース開放しても、アセットバンドル開放しても、MonoがOSから確保したメモリ領域そのものが開放されるわけじゃないので、MemoryWarning自体は解決してないのですけどね・・・