A.用CCFuncBlock可以不用傳參數,代碼簡潔高效,函數內臨時變量如果不retain,不存在跳出函數使用域后被回收情況(推薦)
//用CCCallBlock的block方式 CGPoint convertedLocation = [self convertTouchToNodeSpace:touch]; CCCallBlock *block = [CCCallBlock actionWithBlock:^{ //回調方法在一個函數循環內3個好處:
1.不用傳遞(void *)參數,所以convertedLocation不需要封裝,
2.傳遞指針類型變量(非alloc或copy)也不需要retain,
3.alloc或copy方式產生的參數,函數內釋放,省去函數外手動釋放的麻煩。
[self flightBezier:convertedLocation];
}];
[flight runAction:[CCSequence actions:[CCMoveTo actionWithDuration:1 position:ccp(convertedLocation.x,convertedLocation.y)], block, nil]];
B.使用CCFuncND傳遞參數(void *)類型,若想傳遞CGPoint等非指針類型參數,,有兩種方法:
1.傳遞參數地址,注意參數必須為靜態變量,否則參數地址一出循環即被系統回收。
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; static _startPos; CGPoint convertedLocation = [self convertTouchToNodeSpace:touch]; _startPos = converedLocation; //傳遞&_startPos id call = [CCCallFuncND actionWithTarget:self selector:@selector(call:data:) data:(void *)&_startPos]; [flight runAction:[CCSequence actions:[CCMoveTo actionWithDuration:1 position:ccp(convertedLocation.x,convertedLocation.y)], call, nil]]; return; }
回調:
- (void)call:(id)sender data:(void *)point {
//sender即為flight指針 //傳遞&_startPos; CGPoint p = *(CGPoint *) point; [self flightBezier:p]; }
2.如果想傳遞CGPoint等非指針類型變量, 可以封裝成NSValue再傳遞
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; static _startPos; CGPoint convertedLocation = [self convertTouchToNodeSpace:touch]; _startPos =converedLocation; //傳遞nsvalue封裝的cgpoint NSValue *va = [[NSValuevalueWithCGPoint:convertedLocation]retain];//這里不能加autorease id call1 = [CCCallFuncND actionWithTarget:self selector:@selector(call:data:) data:(void *)va]; [flight runAction:[CCSequence actions:[CCMoveTo actionWithDuration:1 position:ccp(convertedLocation.x,convertedLocation.y)], call1, nil]]; return; }
回調:
- (void)call:(id)sender data:(void *)point { //傳遞nsvalue CGPoint p = [((NSValue *)point) CGPointValue];
//父變量,子釋放,比較忌諱,但是沒找到好的解決辦法先湊合用 [(NSValue *)point release]; point = nil; [self flightBezier:p]; }