According to this article For loops in objective C can be optimized using SEL & IMP. I have been toying with the idea for a bit now, and today I've been trying some tests. However what seems to work for one class, does not seem to work for another. Furthermore, I would like to know how exactly the speedup occurs ? By avoiding objC_mesgSent ?
Question 1 How is this:
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];
Worse than this:
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);
Question 2 Why does this fail ? (Note self is a class that inherits from 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];
The error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SimpleGridView addSubview:]: unrecognized selector sent to instance 0xaa3c400'
Tells me that method addSubview has not been found in my Class "SimpleGridView". However when I tried:
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];
}
I still get the exact same error !
Question 3 Why can't I set a selector & implementation to a Class Init/new method like so:
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);
For reference: Class iContactsGridCell inherits from Class Cell, which defines and implements
- (id) initWithRect:(CGRect)frame;
Furthermore, casting did not help (same error about unrecognized selector)
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);
Trying different combinations such as:
IMP initCellImp = [Cell methodForSelector:initCellSel];
Or
cell = initCellImp([iContactsGridCell class],initCellSel,tmp_frame);
Produce the exact same error. So, please tell me, what am I missing, how is this beneficial and is it possible to have an IMP/SEL for a class init method ? Also, would a C function pointer be faster compared to this, or is all the above simply an objective-C function pointer wrapper ? Thank you ! PS: I apologize if those are too many questions at once.