我正在使用Cocos2d for iPhone,我想知道使用这种方法构建我的代码逻辑以产生敌人是否更有效:
- (void)schedule:(SEL)selector interval:(ccTime)interval
或在EnemyCache类中使用更新,并在每次验证是否满足时间间隔时进行验证。下面是在EnemyCache类的update方法中调用的代码片段(相对时间是一个整数值,由GameScene在GameScene类中的每次更新时更新 - GameScene更新方法调用的间隔为1第二):
-(void) checkForPlayerCollisionsAndSpwanTime
{
int count = [elements count];
//CCLOG(@"count %i", count);
Element* element;
for(int i=0; i<count;i++){
element = [elements objectAtIndex:i];
NSAssert(element!=nil, @"Nil enemy");
if (element.visible)
{
[element justComeDown];
ShipEntity * ship = [[GameScene sharedGameScene]defaultShip];
CGRect rect = [ship boundingBox];
if (CGRectIntersectsRect([element boundingBox], rect)){
[element doWhatever];
element.visible=FALSE;
[element stopAllActions];
}
}
else{
if(element.spawnTime == relativeTime) {
[self addChild:element];
element.visible=TRUE;
}
}
}
}
不同之处在于,在每次更新时, checkForPlayerCollisionsAndSpwanTime 方法都会通过敌人阵列。在第一种方式中,通过调度选择器来调用类似的方法,我可以减少CPU查看数组和条件所花费的时间。
我不确定这次电话有多贵:
[self schedule:selector interval:interval repeat:kCCRepeatForever delay:0];
通过浏览我看到调用此方法(见下文),但我想问一下你对这个问题的处理方法是什么,以及我是否应该继续使用EnemyCache更新方法或使用scheduleSelector方法。
-(void) scheduleSelector:(SEL)selector forTarget:(id)target interval:(ccTime)interval paused:(BOOL)paused repeat:(uint) repeat delay:(ccTime) delay
{
NSAssert( selector != nil, @"Argument selector must be non-nil");
NSAssert( target != nil, @"Argument target must be non-nil");
tHashSelectorEntry *element = NULL;
HASH_FIND_INT(hashForSelectors, &target, element);
if( ! element ) {
element = calloc( sizeof( *element ), 1 );
element->target = [target retain];
HASH_ADD_INT( hashForSelectors, target, element );
// Is this the 1st element ? Then set the pause level to all the selectors of this target
element->paused = paused;
} else
NSAssert( element->paused == paused, @"CCScheduler. Trying to schedule a selector with a pause value different than the target");
if( element->timers == nil )
element->timers = ccArrayNew(10);
else
{
for( unsigned int i=0; i< element->timers->num; i++ ) {
CCTimer *timer = element->timers->arr[i];
if( selector == timer->selector ) {
CCLOG(@"CCScheduler#scheduleSelector. Selector already scheduled. Updating interval from: %.4f to %.4f", timer->interval, interval);
timer->interval = interval;
return;
}
}
ccArrayEnsureExtraCapacity(element->timers, 1);
}
CCTimer *timer = [[CCTimer alloc] initWithTarget:target selector:selector interval:interval repeat:repeat delay:delay];
ccArrayAppendObject(element->timers, timer);
[timer release];
}
答案 0 :(得分:4)
您的应用中是否存在性能问题?如果没有,答案是:没关系。如果你这样做,你是否测量过它并且问题是否来自有问题的方法?如果没有,答案是:你找错了地方。
换句话说:premature optimization is the root of all evil。
如果您仍然想知道,只有一种方法可以找到:测量代码的两种变体并选择更快的代码。如果速度差异很小(我怀疑它会是这样),请使用更容易使用的版本。你应该考虑一种不同的表现:你作为一个人,阅读,理解,改变代码。在几乎所有情况下,代码可读性和可维护性都比性能更重要。
没有人可以(或将会)查看这段代码并得出结论“是的,A肯定要快30-40%,使用A”。如果你担心方法的速度,不要让任何人告诉你哪个更快。测量它。这是你可以肯定的唯一方法。
原因是:程序员因为对代码性能做出假设而臭名昭着。很多时候他们错了,因为语言或硬件或对该主题的理解在他们最后一次测量时已经有了很大的飞跃。但更有可能的是,他们会记住他们所学到的东西,因为一旦他们问过像你这样的问题,而其他人给了他们一个他们从那时起接受的回答。
但回到你的具体例子:这无关紧要。由于渲染了太多的敌人而不是决定何时产生一个的代码,因此你会遇到很多,更多,更多,更可能遇到性能问题。然后真的,真的,真的,真的,真的无关紧要,如果代码是在预定的选择器中运行的,或者是每个帧增加计数器的预定更新方法。这可归结为主观编码风格偏好问题,而不仅仅是对绩效的决定。