AwD*_*ven 2 objective-c cocos2d-iphone
继承人我的问题我正在尝试为iphone的cocos2d中的动作序列创建一个回调函数,但我一直收到错误的访问错误.
在这里,我创建了我的回电
id myCallFunc = [CCCallFuncND actionWithTarget:self.delegate selector:@selector(playerAttack:data:) data:(__bridge void *)([[PlayerAttackPacket alloc] initWithPlayer:@"" attackChoice: [NSNumber numberWithInt: item.tag]]) ]; // to call our method
Run Code Online (Sandbox Code Playgroud)
这里是回调函数,在编译数据时编译器说错误访问.
-(void) playerAttack:(id)sender data:(void *)data
{
PlayerAttackPacket* packet = (__bridge PlayerAttackPacket*)data;
BattleModel *model = [BattleModel sharedInstance];
int choice = packet.attackChoice.intValue;
NSString * players = packet.player;
}
Run Code Online (Sandbox Code Playgroud)
播放器包:
@interface PlayerAttackPacket : NSObject {
NSString * player;
NSNumber * attackChoice;
}
@property (nonatomic, retain) NSString * player;
@property (nonatomic, retain) NSNumber * attackChoice;
-(id) initWithPlayer: (NSString*)_player attackChoice: (NSNumber*)choice;
@end
@implementation PlayerAttackPacket
@synthesize player,attackChoice;
-(id) initWithPlayer: (NSString*)_player attackChoice: (NSNumber*)choice
{
if((self=[super init]))
{
self.player = _player;
self.attackChoice = choice;
}
return self;
}
@end
Run Code Online (Sandbox Code Playgroud)
谁能告诉我我做错了什么?=(.我的感觉是它与ARC有关,但我不确定.
为了便于阅读,这里是你的call func方法重新格式化:
void* data = (__bridge void*)[[PlayerAttackPacket alloc] initWithPlayer:@""
attackChoice: [NSNumber numberWithInt: item.tag]];
id myCallFunc = [CCCallFuncND actionWithTarget:self.delegate
selector:@selector(playerAttack:data:) data:data ];
Run Code Online (Sandbox Code Playgroud)
你做的是这样的:
ARC看到/做的是:
您没有对该对象保持强引用,因此它在执行选择器时释放.请不要使用Ben的建议,我知道它有效,但它也很危险,因为它会在调用func动作没有实际执行选择器的任何时候泄漏内存,即在停止动作/序列或在调用时更改场景时func仍在运行,等待执行选择器.
您可以通过两种方式解决此问题:
一定要使用一个块!它避免了内存管理问题,您也不必对该对象有强引用.事实上,你甚至不必将它传递给块!以下是它的工作原理:
PlayerAttackPacket* packet = [[PlayerAttackPacket alloc] initWithPlayer:@""
attackChoice: [NSNumber numberWithInt: item.tag]];
id myCallBlock = [CCCallBlock actionWithBlock:^{
// no bridge casting required, packet variable is accessible within the block
// no memory management needed, block copies packet and keeps it alive
BattleModel *model = [BattleModel sharedInstance];
int choice = packet.attackChoice.intValue;
NSString * players = packet.player;
}];
Run Code Online (Sandbox Code Playgroud)
现在我在这里猜测,但在我看来,就像你创建了PlayerAttackPacket类一样,只是为了将几个参数传递给CCCallFuncND.您也可以使用块跳过它!
NSString* player = @"player1";
id myCallBlock = [CCCallBlock actionWithBlock:^{
// whatever variables you need from the surrounding scope, you can just use
// them as if they were local variables in the block!
int choice = item.tag;
NSString * players = player;
}];
Run Code Online (Sandbox Code Playgroud)
块非常方便,使用ARC可以更好地工作.使用块!重复:使用块.