Jas*_*ien 6 runtime dynamic objective-c llvm
我刚看到Three20中的一些代码看起来像这样:
SEL sel = @selector(textField:didAddCellAtIndex:);
if ([self.delegate respondsToSelector:sel]) {
[self.delegate performSelector:sel withObject:self withObject:(id)_cellViews.count-1];
}
Run Code Online (Sandbox Code Playgroud)
在LLVM 2.0上,这会导致编译错误:
error:指向接口'id'的指针算术,在非脆弱的ABI中不是常量
我知道为什么会发生错误,我知道如何解决它.我只需要直接调用该方法,如下所示:
SEL sel = @selector(textField:didAddCellAtIndex:);
if ([self.delegate respondsToSelector:sel]) {
[self.delegate textField:self didAddCellAtIndex:(_cellViews.count - 1)];
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果您在编译时知道选择器及其参数,为什么需要performSelector:withObject:withObject:在运行时使用?我不明白为什么代码首先以这种方式编写.如果选择器和参数动态传递给方法,我可能会理解,但它们不是,选择器及其参数是硬编码的(即使索引在运行时确实发生了变化,它获取索引的方法也很难编码.)
如果有人能向我解释为什么有必要这样做,我将不胜感激.否则,我将在这里更改所有这些代码.
Jas*_*ien 10
经过一番挖掘之后,看起来TTPickerTextField这个代码所在的类是a的间接子类UITextField.
因此,它支持UITextFields委托属性,它不符合声明TTPickerTextFieldDelegate方法的协议textField:didAddCellAtIndex:.
我得出结论,这段代码只是懒惰.没有理由为什么UITextFields委托属性必须被捎带,这使得这个令人困惑,容易出错的代码变得必要.
我自己的方法是UITextField单独保留s委托属性,并在我处理特定委托方法的特定子类中添加我自己的属性.
只是为了澄清一下 - 我在问题中提到的'解决方案'修复了编译器错误,但是生成一个警告,说明找不到该方法并且将假定返回id.这就是原始代码"解决"但只适用于GCC.不再使用LLVM 2.0.
最后编辑,我保证:
我最终解决这个懒惰并摆脱警告和错误的解决方案是一个丑陋的黑客:
[(id <TTPickerTextFieldDelegate>)self.delegate textField:self didAddCellAtIndex:(_cellViews.count - 1)];
Run Code Online (Sandbox Code Playgroud)
将UITextField委托转换为id符合TTPickerTextFieldDelegate,然后直接调用该方法.
请不要偷懒:(
respontsToSelector/performSelector组合是可选委托方法的惯用法.委托不保证定义该方法,因此直接调用它会导致编译器警告.
在这种情况下编译器实际抱怨的是:
[self.delegate performSelector:sel withObject:self withObject:(id)_cellViews.count-1];
error: arithmetic on pointer to interface 'id', which is not a constant size in non-fragile ABI
Run Code Online (Sandbox Code Playgroud)
风险指针算术...'id'是指针类型,因此:
(id)_cellViews.count-1
Run Code Online (Sandbox Code Playgroud)
告诉编译器它将从指针中减去一个而不是整数....这可能不是该代码的意图.performSelector的withObject参数必须是指针,它不能是原语.你可以通过在NSNumber中包装_cellViews.count - 1并在委托方法中解包它来解决这个问题.
[self.delegate performSelector:sel withObject:self withObject:[NSNumber numberWithInt:_cellViews.count-1]];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6546 次 |
| 最近记录: |