'从不兼容的类型'分配'id'

时间:2012-09-06 12:17:55

标签: objective-c fast-enumeration

我正在为Box2d实现一个客观的C包装器(用c ++编写)。 b2Body在其userData字段中保留对其包装器B2Body的引用。 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

1 个答案:

答案 0 :(得分: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's article仍然是实现快速枚举的重要来源。

修改

注意到你要返回一个对象。所以,我假设GetUserData只返回一个对象指针。由于您需要返回指向对象指针的指针,您需要执行以下操作:

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

但是,一旦从此方法返回,该堆栈对象将消失,这就是您传递可以使用的堆栈缓冲区的原因。因此,您可能应该将单个指针填充到提供的堆栈缓冲区中:

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