1

Box2d(c ++で記述されている)用のObjectiveCラッパーを実装しています。b2Bodyは、ラッパーB2Bodyへの参照をuserDataフィールドに保持します。GetUserDataはvoid*を返します。私は現在、B2BodiesをB2Worldから取り出すための高速イテレーションを実装しています。

以下に示す行で、互換性のないタイプ「B2Body*」から「ID」への割り当てエラーが発生します。なんで?

#import "B2Body.h"
#import "B2World.h"
#import "Box2d.h"

@implementation B2World

-(id) initWithGravity:(struct B2Vec2) g
{
  if (self = [super init])
  {
    b2Vec2 *gPrim = (b2Vec2*)&g;
    _world = new b2World(*gPrim);
  }

  return self;
}

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len;

{
  if(state->state == 0)
  {
    state->mutationsPtr = (unsigned long *)self;
    state->extra[0] = (long) ((b2World*)_world)->GetBodyList();
    state->state = 1;
  }

  // pull the box2d body out of extra[0]
  b2Body *b = (b2Body*)state->extra[0];

  // if it's nil then we're done enumerating, return 0 to end
  if(b == nil)
  {
    return nil;
  }

  // otherwise, point itemsPtr at the node's value
  state->itemsPtr = ((B2Body*)b->GetUserData()); // ERROR
  state->extra[0] = (long)b->GetNext();

  // we're returning exactly one item
  return 1;
}

`

B2Body.hは次のようになります:#import

@interface B2Body : NSObject
{
  int f;
}

-(id) init;
@end
4

1 に答える 1

2

NSFastEnumerationStateはC構造体であり、itemsPtrフィールドは次のとおりです。

id __unsafe_unretained  *itemsPtr;

以前のバージョンでは、__unsafe_unretained指定子が明らかに欠落していました。

フィールドitemsPtrはIDへのポインタであることに注意してください。idは本質的にポインタなので、itemsPtrはオブジェクトポインタへのポインタです。実際、このフィールドは、高速列挙を可能にするオブジェクトの配列を保持するものです。基本的に、このオブジェクトポインタの配列をトロールします。

私はBox2dについて何も知らないので、それが私が言えることのすべてです。b-> GetUserData()がオブジェクトの配列へのポインタを返すと仮定すると、次のことができるはずです。

state->itemsPtr = (__unsafe_unretained id *)b->GetUserData();

少し古いですが、Mike Ashの記事は、高速列挙を実装するための優れた情報源です。

編集

単一のオブジェクトを返していることに気づきました。したがって、GetUserDataは単一のオブジェクトポインタを返すだけだと思います。オブジェクトポインタへのポインタを返す必要があるため、次のようなことを行う必要があります。

id object = (__bridge id)b->GetUserData();
state->itemsPtr = &object;

ただし、このメソッドから戻ると、そのスタックオブジェクトはなくなります。そのため、使用できるスタックバッファが渡されます。したがって、おそらくその単一のポインタを提供されたスタックバッファに詰め込む必要があります。

*buffer = (__bridge id)b->GetUserData()
state->itemsPtr = buffer;
于 2012-09-06T13:24:04.607 に答える