* kclib1のページ#6
-(by [[K]], 2019.04.16)
** (10) KAutoreleasePool
-仕事でObjective-Cを使った時に、autoreleasePoolの仕組みが便利だなと感じたので、似たようなものを作ってみました(本家よりもかなりシンプルですが)。
-Objective-Cを知らない人向けに言うと、「使わなくなったオブジェクトを自動でfreeしてくれる便利な仕組み」って感じです。
----
-KAutoreleasePool *KAutoreleasePool_open()
--自動解放プールをオープンします。以後は自動的にこのプールがデフォルトになります。
-void KAutoreleasePool_add(KAutoreleasePool *w, int s, void *p)
--自動解放プールに、サイズとポインタを登録します。wに0を指定した場合はデフォルトのプールへの登録になります。
-int KAutoreleasePool_remove(KAutoreleasePool *w, void *p)
--自動解放プールに登録されているポインタを削除します。戻り値は登録されていたサイズです。
--これのあとにaddを使うことで、登録されたポインタを別のプールに付け替えることもできます。
-void *KAutoreleasePool_alloc(KAutoreleasePool *w, int s)
--sを使ってKMallocして、取得したポインタを直ちに自動解放プールに登録して、それでそれを返します。
-void KAutoreleasePool_close(KAutoreleasePool *w)
--自動解放プールを閉じます。つまりこの時点でプール内のすべてのポインタがfreeされることになります。
----
-[内部実装]
 typedef struct KAutoreleaseNode_ {
     void *p;
     int s;
     void *n;
 } KAutoreleaseNode;
 
 typedef struct KAutoreleasePool_ {
     void *prv;
     KAutoreleaseNode *n;
 } KAutoreleasePool;
----
-[内部実装]
 #include "kclib1.h"
 
 KAutoreleasePool *KAutoreleasePool_top;
 static KPtrPool *nodePool;
 
 KAutoreleasePool *KAutoreleasePool_open()
 {
     KAutoreleasePool *w;
     if (KMalloc_work->p == 0)
         KMalloc_init();
     if (nodePool == 0)
         nodePool = KMalloc_work->p + KMalloc_index(sizeof (KAutoreleaseNode));
     w = KMalloc_alloc(sizeof (KAutoreleasePool));
     w->prv = KAutoreleasePool_top;
     KAutoreleasePool_top = w;
     w->n = 0;
     return w;
 }
 
 void KAutoreleasePool_add(KAutoreleasePool *w, int s, void *p)
 {
     KAutoreleaseNode *n;
     if (w == 0) w = KAutoreleasePool_top;
     n = KPtrPool_alloc(nodePool);
     n->n = w->n;
     n->p = p;
     n->s = s;
     w->n = n;
 }
 
 int KAutoreleasePool_remove(KAutoreleasePool *w, void *p)
 {
     KAutoreleaseNode *n, *m = 0;
     if (w == 0) w = KAutoreleasePool_top;
     n = w->n;
     while (n != 0) {
         if (n->p == p) {
             int s = n->s;
             if (m != 0)
                 m->n = n->n;
             else
                 w->n = n->n;
             KPtrPool_free(nodePool, n);
             return s;
         }
         m = n;
         n = n->n;
     }
     kerrorExit("KAutoreleasePool_remove: not found: p=%08x", p);
     return -1; // dummy.
 }
 
 void *KAutoreleasePool_alloc(KAutoreleasePool *w, int s)
 {
     void *p = KMalloc_alloc(s);
     KAutoreleasePool_add(w, s, p);
     return p;
 }
 
 void KAutoreleasePool_close(KAutoreleasePool *w)
 {
     KAutoreleaseNode *n, *nn;
     if (w != KAutoreleasePool_top)
         kerrorExit("KAutoreleasePool_close: nesting error");
     for (n = w->n; n != 0; ) {
         nn = n->n;
         KMalloc_free(n->s, n->p);
         KPtrPool_free(nodePool, n);
         n = nn;
     }
     KAutoreleasePool_top = w->prv;
     KMalloc_free(sizeof (KAutoreleasePool), w);
 }

* こめんと欄
#comment

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS