我正在为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
答案 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;