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

问题是如何在performSelectorInBackgroundcell中发送和string作为参数,有什么想法吗?@selector

谢谢 ..

4

4 回答 4

10

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

如果你想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

您可以将 anNSDictionary*或 an传递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...
}

我个人更喜欢它NSDictionaryNSArray因为它看起来更清晰。

于 2013-06-24T15:15:15.250 回答
2

问题是如何将“单元格”和“字符串”作为参数发送到 performSelectorInBackground 中的@selector,有什么想法吗?

你不能。 @selector()是一个编译器指令,它简单地将括号之间的任何内容转换为一个 Objective-C 选择器——你不能给它任何其他参数。我认为您真正想要做的是使用参数调用选择器。您尝试使用的方法仅允许使用单个参数;没有办法提供超过一个。

使用块或调用。但这并不意味着您没有其他选择。您可以使用块,如 Rob 所述,或者您可以创建 NSInvocation 的实例,添加必要的参数,设置选择器和目标,然后调用-invoke.

于 2013-06-24T15:19:29.960 回答
0

您只能使用 performSelectorInBackground 发送一个参数。

您必须对代码进行一些重新架构。

要传递您执行的参数之一:

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