根据这篇文章,目标 C 中的 For 循环可以使用 SEL 和 IMP 进行优化。我一直在玩弄这个想法,今天我一直在尝试一些测试。然而,似乎对一个班级有效,似乎对另一个班级无效。此外,我想知道加速究竟是如何发生的?通过避免 objC_mesgSent?
问题 1 这是怎么回事:
Cell *cell;
for (NSMutableArray *row in self.data) {
for (Data *d in row){
cell = [[Cell alloc] initWithRect:tmp_frame];
[self addSubview:cell.view];
[self.cells addObject:cell];
比这更糟糕:
SEL addCellSel = @selector(addObject:);
IMP addCellImp = [self.cells methodForSelector:addCellSel];
Cell *cell;
for (NSMutableArray *row in self.data) {
for (Data *d in row){
cell = [[Cell alloc] initWithRect:tmp_frame];
[self addSubview:cell.view];
addCellImp(self.cells,addCellSel,cell);
问题 2 为什么会失败?(注意self是继承自UIView的类)
SEL addViewSel = @selector(addSubview:);
IMP addViewImp = [self methodForSelector:addViewSel];
Cell *cell;
for (NSMutableArray *row in self.data) {
for (Data *d in row){
cell = [[Cell alloc] initWithRect:tmp_frame];
addViewImp(self,addViewSel,cell.view);
[self.cells addObject:cell];
错误:
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[SimpleGridView addSubview:]:无法识别的选择器发送到实例 0xaa3c400”
告诉我在我的“SimpleGridView”类中找不到方法addSubview。但是,当我尝试时:
if ([self respondsToSelector:addViewSel]){
NSLog(@"self respondsToSelector(AddViewSel)");
addViewImp(self,addViewSel,cell.view);
} else {
NSLog(@"self does not respond to selector (addViewSel");
[self addSubview:cell.view];
}
我仍然得到完全相同的错误!
问题 3 为什么我不能像这样将选择器和实现设置为 Class Init/new 方法:
iContactsGridCell *cell;
SEL initCellSel = @selector(initWithRect:);
IMP initCellImp = [iContactsGridCell methodForSelector:initCellSel];
for (NSMutableArray *row in self.data) {
for (Data *d in row){
cell = initCellImp([iContactsGridCell new],initCellSel,tmp_frame);
供参考:类iContactsGridCell继承自 Class Cell,它定义和实现
- (id) initWithRect:(CGRect)frame;
此外,强制转换没有帮助(关于无法识别的选择器的相同错误)
iContactsGridCell *cell;
SEL initCellSel = @selector(initWithRect:);
IMP initCellImp = [Cell methodForSelector:initCellSel];
for (NSMutableArray *row in self.data) {
for (Data *d in row){
cell = (iContactsGridCell *)initCellImp([Cell new],initCellSel,tmp_frame);
尝试不同的组合,例如:
IMP initCellImp = [Cell methodForSelector:initCellSel];
或者
cell = initCellImp([iContactsGridCell class],initCellSel,tmp_frame);
产生完全相同的错误。所以,请告诉我,我错过了什么,这有什么好处,是否有可能为类 init 方法提供 IMP/SEL?此外,与此相比,C 函数指针会更快,还是以上所有内容都只是一个目标 C 函数指针包装器?谢谢 !PS:如果这些问题一次太多,我深表歉意。