我有一个专为iPhone OS 2.x设计的应用程序。
在某些时候我有这个代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//... previous stuff initializing the cell and the identifier
cell = [[[UITableViewCell alloc]
initWithFrame:CGRectZero
reuseIdentifier:myIdentifier] autorelease]; // A
// ... more stuff
}
但由于initWithFrame选择器在3.0中已弃用,我需要使用respondToSelector和performSelector转换此代码......因此...
if ( [cell respondsToSelector:@selector(initWithFrame:)] ) { // iphone 2.0
// [cell performSelector:@selector(initWithFrame:) ... ???? what?
}
我的问题是:如果我必须传递两个参数“initWithFrame:CGRectZero”和“reuseIdentifier:myIdentifier”???我可以如何将A上的调用断开到preformSelector调用?
编辑 - 由于fbrereto的消化,我做了这个
[cell performSelector:@selector(initWithFrame:reuseIdentifier:)
withObject:CGRectZero
withObject:myIdentifier];
我遇到的错误是“'performSelector:withObject:withObject'的参数2的不兼容类型。
myIdentifier声明为
static NSString *myIdentifier = @"Normal";
我试图将呼叫更改为
[cell performSelector:@selector(initWithFrame:reuseIdentifier:)
withObject:CGRectZero
withObject:[NSString stringWithString:myIdentifier]];
没有成功......
另一点是CGRectZero不是一个对象...
答案 0 :(得分:11)
使用NSInvocation
。
NSInvocation* invoc = [NSInvocation invocationWithMethodSignature:
[cell methodSignatureForSelector:
@selector(initWithFrame:reuseIdentifier:)]];
[invoc setTarget:cell];
[invoc setSelector:@selector(initWithFrame:reuseIdentifier:)];
CGRect arg2 = CGRectZero;
[invoc setArgument:&arg2 atIndex:2];
[invoc setArgument:&myIdentifier atIndex:3];
[invoc invoke];
或者,直接调用objc_msgSend
(跳过所有不必要的复杂高级构造):
cell = objc_msgSend(cell, @selector(initWithFrame:reuseIdentifier:),
CGRectZero, myIdentifier);
答案 1 :(得分:1)
您要使用的选择器实际上是@selector(initWithFrame:reuseIdentifier:)
。要传递两个参数,请使用performSelector:withObject:withObject:
。获取参数可能需要一些试验和错误,但它应该有效。如果不是,我建议探索旨在处理更复杂的消息调度的NSInvocation
类。