2009-10-06 23 views
2
-(void)setX:(int)x andY:(int)y andObject:(Sprite*)obj 
{ 
    [obj setPosition:CGPointMake(x,y)]; 
} 

現在,我想要使用以下定時器調用上述方法。如何在調用函數時使用定時器在目標c中傳遞參數

[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector() userInfo:nil repeats:NO]; 

要在這裏設置什麼?

如何傳遞參數? (根據我的知識 - 選擇器只指定要調用的方法)

+1

看看這個qu http://stackoverflow.com/questions/1349740/arguments-in-selector/ – 2009-10-06 19:08:59

+0

評論是答案...... – 2009-10-06 19:13:39

回答

5

通過Matt Ball從一個答案複製:

- (void)startMyTimer { 
     /* ... Some stuff ... */ 
     NSDictionary *userDict; 
     userDict = [NSDictionary dictionaryWithObjectsAndKeys:someValue, 
                   @"value1", 
                   someOtherValue, 
                   @"value2", nil]; 

     [NSTimer scheduledTimerWithTimeInterval:0.1 
             target:self 
             selector:@selector(callMyMethod:) 
             userInfo:userDict 
             repeats:YES]; 
} 
    - (void)callMyMethod:(NSTimer *)theTimer { 
     NSString *value1 = [[theTimer userInfo] objectForKey:@"value1"]; 
     NSString *value2 = [[theTimer userInfo] objectForKey:@"value2"]; 
     [self myMethod:value1 setValue2:value2]; 
    } 
+0

Upvoted;黑客......確實......但有時候黑客是你所需要的。 *拍手* – bbum 2009-10-07 07:14:16

+3

我沒有說這是錯的。我把它提高了。工作正常...... * hack *指的是它正在做拳擊/拆箱,因此,所有類型的安全性都會丟失,同時也會增加脆弱性。沒有錯;只是要注意的事情。 – bbum 2009-10-08 22:32:56

+0

我應該使用'hacque'這個詞來表示它是一流的hacque。 :) – bbum 2009-10-09 20:01:25

1

您可以將一個NSDictionary *或其他某個對象作爲userInfo傳遞,並將參數放入該對象中。

+0

好的。但如何通過NSDictionary? – 2009-10-06 19:09:36

+0

完成,請參閱我的答案。 – 2009-10-06 19:21:11

2

如果使用目標動作計時器,則不能讓計時器直接調用任意方法。計時器的動作必須具有非常具體的簽名。你可以在userinfo字典中傳遞額外的數據,讓計時器的動作調用你最終想要的方法,或者你可以像Dave說的那樣使用調用形式。就我個人而言,我通常會做前者,因爲我覺得NSInvocations很煩人,而設置一個實際上可以採用更多的代碼,而不僅僅是編寫中介方法。

6

如果你有一組相當複雜的參數,你想用來調用該方法,我會建議將參數捕獲到持有配置的東西,並可以根據該配置做任何需要做的事情。 。

的東西,像這樣的接口:

PositionSetter.h:

@interface PositionSetter : NSObject 
{ 
    NSInteger x; 
    NSInteger y; 
    Sprite *target; 
} 

+ positionSetterWithX: (NSInteger) xPos y: (NSInteger) yPos sprite: (Sprite *) aSprite; 

- (void) applyPosition; 
@end 

PositionSetter.m:

@interface PositionSetter() 
@property(readwrite, nonatomic) NSInteger x; 
@property(readwrite, nonatomic) NSInteger y; 
@property(readwrite, nonatomic, retain) Sprite *target; 
@end 

@implementation PositionSetter 
@synthesize x, y, target; 

+ positionSetterWithX: (NSInteger) xPos y: (NSInteger) yPos sprite: (Sprite *) aSprite; 
{ 
    PositionSetter *positionSetter = [PositionSetter new]; 
    positionSetter.x = xPos; 
    positionSetter.y = yPos; 
    positionSetter.target = aSprite; 
    return [positionSetter autorelease]; 
} 

- (void) applyPosition; 
{ 
    [self.target setPosition:CGPointMake(self.x,self.y)]; 
} 
@end 

用法非常簡單:

positionSetter = [PositionSetter positionSetterWithX: 42 y: 21 sprite: mySprite]; 
[positionSetter performSelector: @selector(applyPosition) withObject: nil afterDelay: 1.0]; 

雖然一點點更多的代碼,生成的實施將是速度不夠快 - 可能比NSInvocation的快,但速度不夠快給無關,這是會導致繪圖 - 而且更靈活多了。我可以很容易地看到重構上述動作,比如CoreAnimation。

+0

先生,您不覺得這是一個複雜的解決方案。 是不是他們的小動作? – 2009-10-06 18:37:31

+0

最簡單的方法,請參閱我的問題下面的評論 - 或看到我的答案。 – 2009-10-06 19:21:57

+0

簡單並不總是最好的。你的答案肯定有效,但我討厭必須維護或重構該代碼。與此同時,快速黑客往往比優雅的代碼更有效地支付賬單。 ;) – bbum 2009-10-07 07:13:41

0

作爲替代的NSTimer,在iOS 4.0+和10.6 +,你可以使用大中央調度和調度資源,以做到這一點使用的塊。蘋果已經爲這個在他們Concurrency Programming Guide下面的代碼:

dispatch_source_t CreateDispatchTimer(uint64_t interval, uint64_t leeway, dispatch_queue_t queue, dispatch_block_t block) 
{ 
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 
    if (timer) 
    { 
     dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway); 
     dispatch_source_set_event_handler(timer, block); 
     dispatch_resume(timer); 
    } 
    return timer; 
} 

然後,您可以設置使用如下代碼一秒的計時器事件:

dispatch_source_t newTimer = CreateDispatchTimer(1ull * NSEC_PER_SEC, (1ull * NSEC_PER_SEC)/10, dispatch_get_main_queue(), ^{ 
    [self setX:someValue andY:otherValue andObject:obj]; 
}); 

只要你儲存和釋放你的計時器完成後。這甚至可以讓你觸發一個定時器,通過使用併發隊列而不是上面使用的主隊列來在後臺線程上執行項目。

這可以避免需要裝箱和取消裝箱參數。

0

使用這些參數創建字典並使用timer userinfo傳遞該字典。這將解決你的問題

相關問題