idとdoubleの相互変換 (その2)

リファレンスのコードだったが、残念だがこれでは上手く行かない。テストしてみればわかるのだが、ivarにint型の値を設定した呼び出しだとテストが通るのだが、double等の実数だと想定したように値を読み書きできないのである。

ダンプで明らかになったが、_object_setInstanceVariable渡ってくるパラメタの値のサイズは型のサイズであり、前回のコードにように単にvoid*では駄目だということだ。

いよいよ諦めかと思ったが、この関数のお陰で実現できそうな気がしてきた。

NSGetSizeAndAlignment

NSGetSizeAndAlignmentはエンコードされた型文字で表された型のサイズとアライメントを取得する。

Ivar _object_setInstanceVariable(id obj, const char *name, void *value)
{
    Ivar ivar = NULL;    
    if (obj && name) {
        if ((ivar = class_getInstanceVariable(object_getClass(obj), name))) 
        {
            const char* type = ivar_getTypeEncoding(ivar);
            NSUInteger size;
            NSUInteger align;
            NSGetSizeAndAlignment(type, &size, &align);
            //対象のivarに対してvalue*からパラメタの型のサイズ分コピー
        }
    }
    return ivar;
}

これでいいのではないかと。
ivarのコピー方法はivarの構造とそれを扱う低レベルのコーディングが必要なため、私にはもう少し勉強が必要だ。