2

アバウトを読みました@selectorが、質問に対する答えが見つかりませんでした

にパラメータを渡そうとしています@selector。これは私がやったことについての簡単なコードです:

- (void)viewDidLoad{
    [super viewDidLoad];

    NewsCell *cell = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    if (cell == nil){
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"NewsCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }
    NSString *string = @"image.png";

    [self performSelectorInBackground:@selector(doSomeThing::) withObject:nil];
}

-(void) doSomeThing:(UITableViewCell *)newsCell imageName:(NSString *)imageName{
    NSLog(@"newsCell: %@", newsCell);
    NSLog(@"imageName: %@", imageName);
}

という名前の新しいUITableViewCellcellを作成しました。別のnibファイルからロードされます。NewsCell

という新しい文字列を作成しましたstring

cell問題は、stringパラメータとして@selectorperformSelectorInBackground送信する方法です。アイデアはありますか??

ありがとう ..

4

4 に答える 4

10

performSelectorInBackground(パラメーターを使用して) を使用して、1 つのパラメーターのみを渡すことができwithObjectます。

2 つのパラメーターを使用してバックグラウンドで実行する場合doSomeThingは、次のことができます。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self doSomeThing:cell imageName:string];
});

ところで、doSomeThing最終的に UI の更新を行う場合は、必ずメイン キューにディスパッチして戻してください。

-(void) doSomeThing:(UITableViewCell *)newsCell imageName:(NSString *)imageName {

    // do your slow stuff in the background here

    NSLog(@"newsCell: %@", newsCell);
    NSLog(@"imageName: %@", imageName);

    // now update your UI

    dispatch_async(dispatch_get_main_queue(), ^{
        // update your UI here
    });
}

最後の注意点として、セルを非同期で更新している場合、本当に注意したい場合は、非同期メソッドが完了するまでにセルが画面からスクロールアウトする可能性があるという事実に注意する必要があります (そしてさらに悪いことに、UITableViewそのセルをテーブルの別の行に再利用した可能性があります)。したがって、セルがまだ画面に表示されていることを確認する必要がある場合があります。したがって、indexPathセルではなくパラメーターを渡し、メソッドを使用しますUITableView。非常によく似た名前のメソッドcellForRowAtIndexPathと混同しないようにして、それがまだ表示されているかどうかを確認します。UITableViewDataSourcetableView:cellForRowAtIndexPath

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self doSomeThing:indexPath imageName:string];
});

その後

-(void) doSomeThing:(NSIndexPath *)indexPath imageName:(NSString *)imageName {

    // do your slow stuff in the background here

    NSLog(@"newsCell: %@", newsCell);
    NSLog(@"imageName: %@", imageName);

    // now update your UI

    dispatch_async(dispatch_get_main_queue(), ^{
        UITableViewCell *newsCell = [self.tableView cellForRowAtIndexPath:indexPath];
        if (newsCell)
        {
            // the cell is still visible, so update your UI here
        }
    });
}
于 2013-06-24T15:14:05.227 に答える
5

NSDictionary*またはNSArray*を に渡すことができますperformSelectorInBackground:

-(void)viewDidLoad {
    // Blah blah 
    NSDictionary* params = @{@"cell": cell, @"image": string};
    [self performSelectorInBackground:@selector(doSomething:) withObject:params];
}

-(void)doSomething:(NSDictionary*)params {
    UITableViewCell* cell = params[@"cell"];
    NSString* image = params[@"image"];

    // Blah blah...
}

個人的にはより鮮明に見えるので好きNSDictionaryです。NSArray

于 2013-06-24T15:15:15.250 に答える
2

問題は、「セル」と「文字列」をパラメーターとして performSelectorInBackground の @selector に送信する方法です。アイデアはありますか??

できません。 @selector()は、括弧内にあるものを単に目的の C セレクターに変換するコンパイラ ディレクティブです。他のパラメーターを指定することはできません。あなたが本当にやりたいことは、パラメーターを指定してセレクターを呼び出すことだと思います。使用しようとしているメソッドでは、1 つのパラメーターしか使用できません。複数提供する方法はありません。

ブロックまたは呼び出しを使用します。ただし、他のオプションがないというわけではありません。Rob が説明するように、ブロックを使用するか、NSInvocation のインスタンスを作成し、必要なパラメーターを追加し、セレクターとターゲットを設定して、-invoke.

于 2013-06-24T15:19:29.960 に答える
0

performSelectorInBackground で送信できるパラメーターは 1 つだけです。

コードの再構築を行う必要があります。

パラメータの 1 つを渡すには、次のようにします。

[self performSelectInBackground:@selector(doSomething:) withObject:cell];
于 2013-06-24T15:15:19.490 に答える