在performSelectorInBackground中将参数传递给@selector?

Muj*_*aFR 2 iphone cocoa-touch objective-c ios

我读过一篇关于@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);
}
Run Code Online (Sandbox Code Playgroud)

我已经创造了新的UITableViewCell叫cell,它从另一个加载笔尖称为文件NewsCell

并创造了新的字符串名为string

问题是如何在performSelectorInBackground中发送cell和string作为参数,任何想法?@selector

谢谢 ..

Rob*_*Rob 10

您只能使用performSelectorInBackground(使用withObject参数)传递一个参数.

如果您想doSomeThing在后台使用两个参数,您可以:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self doSomeThing:cell imageName:string];
});
Run Code Online (Sandbox Code Playgroud)

顺便说一下,如果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
    });
}
Run Code Online (Sandbox Code Playgroud)

最后需要注意的是,如果要异步更新单元格,如果要非常小心,可能需要对异步方法完成时单元格可能已从屏幕滚动的事实敏感(并且更糟糕的是,UITableView可能已经将该单元重用于该表的另一行).因此,您可能需要检查以确保单元格仍在屏幕上.因此,传递indexPath参数而不是单元格,然后使用该UITableView方法,cellForRowAtIndexPath不要与名称相似的UITableViewDataSource方法混淆tableView:cellForRowAtIndexPath,看看它是否仍然可见:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self doSomeThing:indexPath imageName:string];
});
Run Code Online (Sandbox Code Playgroud)

然后

-(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
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 绝对是最好的解决方案,很棒的答案 (3认同)
  • 与此相比,`performSelectorInBackground`看起来很苍白 (2认同)

Kha*_*yen 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...
}
Run Code Online (Sandbox Code Playgroud)

我个人更喜欢NSDictionary到NSArray,因为它看起来更清晰.