30

NSTimer 呼び出しのために userInfo を介してデータを渡そうとしています。これを行う最善の方法は何ですか?NSDictionary を使用しようとしています。Objective-C オブジェクトがある場合、これは十分に単純ですが、他のデータはどうでしょうか? 私はこのようなことをしたいのですが、そのままでは機能しません:

- (void)play:(SystemSoundID)sound target:(id)target callbackSelector:(SEL)selector
{
    NSLog(@"pause ipod");
    [iPodController pause];
    theSound = sound;

    NSMutableDictionary *cb = [[NSMutableDictionary alloc] init];
    [cb setObject:(id)&sound forKey:@"sound"];
    [cb setObject:target forKey:@"target"];
    [cb setObject:(id)&selector forKey:@"selector"];

    [NSTimer scheduledTimerWithTimeInterval:0
                                     target:self
                                   selector:@selector(notifyPause1:)
                                   userInfo:(id)cb
                                    repeats:NO];
}
4

6 に答える 6

52

情報を辞書に正しくラップする必要があります。

- (void) play:(SystemSoundID)sound target:(id)target callbackSelector:(SEL)selector
{
    NSLog(@"pause ipod");
    [iPodController pause];
    theSound = sound;

    NSMutableDictionary *cb = [[NSMutableDictionary alloc] init];
    [cb setObject:[NSNumber numberWithInt:sound] forKey:@"sound"];
    [cb setObject:target forKey:@"target"];
    [cb setObject:NSStringFromSelector(selector) forKey:@"selector"];

    [NSTimer scheduledTimerWithTimeInterval:0
                                     target:self
                                   selector:@selector(notifyPause1:)
                                   userInfo:cb 
                                     repeats:NO];
    [cb release];

}

ではnotifyPause1:、次のすべてを取得します。

- (void)notifyPause1:(NSTimer *)timer {
    NSDictionary *dict = [timer userInfo];

    SystemSoundID sound = [[dict objectForKey:@"sound"] intValue];
    id target = [dict objectForKey:@"target"];
    SEL selector = NSSelectorFromString([dict objectForKey:@"selector"]);

    // Do whatever...
}

タイマーは繰り返しタイマーなので、もう辞書は必要ありませんので、解放してください。

于 2010-04-16T15:45:53.603 に答える
7

あなたの呼び出しは正しいですが、辞書を id にキャストする必要はありません。notifyPause1: メソッドの次の行で userInfo を取得できます。

- (void)notifyPause1:(NSTimer *)timer {

    NSDictionary *dict = [timer userInfo];

}
于 2010-04-16T09:38:12.873 に答える
6

あなたはセレクターに与えられた方法でタイマーを求めるかもしれません、

次に、そのタイマー( timer.userInfo)からuseInfoを取得できます。

- (void)settingTimer
{
[NSTimer scheduledTimerWithTimeInterval:kYourTimeInterval
                                 target:self
                               selector:@selector(timerFired:)
                               userInfo:yourObject
                                repeats:NO];
}

- (void)timerFired:(NSTimer*)theTimer
{
  id yourObject = theTimer.userInfo;
  //your code here
}
于 2012-01-25T14:12:28.070 に答える
2

sound and selector aren't Objective-C objects: sound is an unsigned number and selector is a pointer to a C struct . That's likely to cause a crash of some sort.

You'll want to use NSValue to hold the value for selector and NSNumber to hold the value for sound. NSValue and NSNumber are objects and will work with the NSMutableDictionary.

于 2010-04-16T10:02:43.223 に答える
2

Laurent Etiemble のメソッドは、さまざまなビュー コントローラーで簡単に使用できる UIViewcontroller のサブクラスでタイマー メソッドをうまく利用するのに適しています。

以下は、ビューを NSTimer userInfo に渡すことで、同じアプリで何度も使用できる一般的なスコア表示を作成する方法です。

.h (UIViewcontroller のサブクラス)

  - (NSTimeInterval) timeSet;
  - (void) timeRun: (UISegmentedControl*)scoreDisplay;
  - (void) timeWrite: (NSTimer *)timer;

.m

            - (NSTimeInterval) timeSet {
                return [self.startTime timeIntervalSinceNow];
            }

            - (void) timeWrite: (NSTimer *)timer
            {
                NSDictionary *dict = [timer userInfo];
                UISegmentedControl *scoreDisplay = [dict objectForKey:@"scoreDisplay"];

                int myint = round([self timeSet]);
                NSString* buttonWrite = [[[NSString stringWithFormat:@"Score: %d", self.answered] stringByAppendingString:[NSString stringWithFormat:@" Errors: %d", self.errors]] stringByAppendingString:[NSString stringWithFormat:@" Time: %d", (myint*-1)]];

                [scoreDisplay setTitle:buttonWrite forSegmentAtIndex:0];
            }

            - (void) timeRun: (UISegmentedControl*)scoreDisplay
            {
                self.startTime = [NSDate date];

                NSMutableDictionary *cb = [[NSMutableDictionary alloc] init];
                [cb setObject:scoreDisplay forKey:@"scoreDisplay"];

                self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1
                                                                target:self
                                                              selector:@selector(timeWrite:)
                                                              userInfo:cb
                                                               repeats:YES];

            }

ビューコントローラーで

.m

  - (void)viewDidLoad
  {
       [super viewDidLoad];

       //load ScoreDisplay
       [self timeRun:self.scoreDisplay];

  }
于 2013-03-30T11:14:40.690 に答える
0

You should not cast your objects to id when assigning to the dictionary. Any object that can be embedded directly into a NSDictionary already derives from NSObject and are implicitly concidered cast to id. Store the name of the selector as an NSString (using NSStringFromSelector()) and then convert it back to a selector using NSSelectorFromString()

Claus

于 2010-04-16T10:05:58.503 に答える