Пришла мне как-то в голову идея, а можно ли взять блок и отдать для target-action?
Есть готовые решения, как к примеру BlocksKit и другие библиотеки, однако их решение заключается в сохранении блока, установкой таргета и вызова блока из указанного селектора.
Зачем тогда нужна эта статья?
Я захотел создать способ генерации селектора, по которому будет вызван блок. Что здесь сложного, скажете вы? imp_implementationWithBlock + class_addMethod и дело закрыто. Но при этом подходе есть одно серьезное требование, это первый аргумент блока — владелец метода.
Как обойти это требование и сделать такое?
[button addTarget:self action:[self ax_lambda:^(UIButton *sender, UIEvent *event){
NSLog(@"click on button %@, event = %@", sender, event);
}] forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:[self ax_lambda:^{
NSLog(@"click");
}] forControlEvents:UIControlEventTouchUpInside];
Или даже вот так
__block NSInteger sum = 0;
[self performSelector:[self ax_lambda:^(NSNumber *argA, NSNumber *argB) {
sum = [argA integerValue] + [argB integerValue];
}] withObject:@(2) withObject:@(3)];
//sum — 5
SEL selSum = [self ax_lambda:^NSInteger(NSInteger argA, NSInteger argB){
return argA + argB;
}];
NSInteger(*funcSum)(id, SEL, NSInteger, NSInteger) = (NSInteger(*)(id, SEL, NSInteger, NSInteger))objc_msgSend;
NSInteger sum2 = funcSum(self, selSum, 2, 3);
//sum2 — 5
Реализация оказалась настолько интересной, что я решил написать об этом.
Читать полностью »