IMP はこのように返り値が id 型の関数として定義されていまして、オブジェクト以外の値を返す IMP に対しても問答無用で retain してしまい、結果落ちるというわです。 適切にキャストしてやればよいのですが、ただのキャストではだめで __bridge を使って「retain するな」ということを明示しなければなりません。 NSInteger result=(NSInteger)(__bridge void*)imp(self, _cmd); このコードはめでたく落ちないんですけど、返り値が id 型より大きい double や NSRect なんかだとこういう風にキャストできない。 じゃあどうすればいいか。受け取った id の型をキャストするのではなく、関数定義そのものをキャストしてしまおうというのが今回のポイントです。