我读了一篇关于@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);
}
我创建了名为cell
的新 UITableViewCell ,它从另一个名为NewsCell
的 nib 文件加载
并创建了名为string
问题是如何将cell
和string
作为参数发送到 performSelectorInBackground 中的@selector
,任何想法?
谢谢..
答案 0 :(得分: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
,不要与名称相似的UITableViewDataSource
方法{{3}混淆,看看它是否仍然可见:
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
}
});
}
答案 1 :(得分: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
,因为它看起来更清晰。
答案 2 :(得分:2)
问题是如何将'cell'和'string'作为参数发送到performSelectorInBackground中的@selector,任何想法?
你不能。 @selector()
是一个编译器指令,它只是将括号中的任何内容转换为Objective-C选择器 - 你不能给它任何其他参数。我认为你真正想做的是用参数调用选择器。您尝试使用的方法只允许使用单个参数;没有办法提供多个。
使用块或调用。但这并不意味着您没有其他选项。您可以像Rob描述的那样使用块,或者您可以创建NSInvocation的实例,添加必要的参数,设置选择器和目标,然后调用-invoke
。
答案 3 :(得分:0)
您只能使用performSelectorInBackground发送一个参数。
您必须对代码进行一些重新构建。
要传递其中一个参数:
[self performSelectInBackground:@selector(doSomething:) withObject:cell];