1

我正在为 Box2d(用 c++ 编写)实现一个目标 C 包装器。b2Body 在其 userData 字段中保留对其包装器 B2Body 的引用。GetUserData 返回一个 void*。我现在正在实施快速迭代以使 B2Bodies 脱离 B2World。

在下面指示的行中,我从不兼容的类型 'B2Body *' 错误中得到一个 'Assigning to '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 回答