Согласно этой статье Циклы в объекте C можно оптимизировать с помощью ВЫБОР И ИМП. Я немного поигрался с этой идеей, а сегодня попробовал несколько тестов. Однако то, что работает для одного класса, не работает для другого. Кроме того, хотелось бы знать, как именно происходит ускорение? Избегая 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»
Сообщает мне, что метод addSubview не найден в моем классе SimpleGridView. Однако когда я попробовал:
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 наследуется от класса 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];
Or
cell = initCellImp([iContactsGridCell class],initCellSel,tmp_frame);
Вывести точно такую же ошибку. Итак, скажите, что мне не хватает, чем это полезно и возможно ли иметь IMP / SEL для метода инициализации класса? Кроме того, будет ли указатель на функцию C быть быстрее по сравнению с этим, или все вышеперечисленное - это просто оболочка указателя на целевую функцию C? Спасибо ! PS: Прошу прощения, если это слишком много вопросов сразу.
-[Cell initWithRect:]
является узким местом, не имеет никакого отношения к тому, что отправка сообщения является узким местом. Это будет отображаться какobjc_mgsSend()
. - person Lily Ballard   schedule 21.12.2012