Имам два класа. Delegator
използва делегиране, за да изпрати своя резултат. Blocker
използва блокове в статични методи.
Без да променям Delegator
, как мога да елегантно и лесно внедря methodWithBlock
, така че блокът да бъде извикан с резултата, произведен от methodWithDelegate
?
Делегатор:
@class Delegator;
@protocol Delegate <NSObject>
- (void)delegator:(Delegator *)sender producedResult:(int)result;
@end
@interface Delegator : NSObject
@property (weak, nonatomic) id <Delegate> delegate;
- (void)methodWithDelegate;
@end
@implementation Delegator
- (void)methodWithDelegate
{
// Some asynchronous computation resulting in
[self.delegate delegator:self producedResult:42];
}
@end
Блокатор:
@interface Blocker : NSObject
+ (void)methodWithBlock:(void(^)(int result))block;
@end
@implementation Blocker
+ (void)methodWithBlock:(void(^)(int result))block
{
// How to call Delegator's methodWithDelegate and return
// the result using block ?
...
}
@end
Изследвани решения:
Обвийте
Delegator
в нов клас или категория и създайте метод, който връща блок, както е предложено в този отговор. Тези решения работят, но са твърде сложни и отнемат много време.Накарайте
Blocker
да съответства на протоколаDelegate
и запазете блока в свойство, инстанцирайте го в рамките на методаmethodWithBlock
и извикайте блока, когато се извика методът за делегиране. Това не работи, тъй като няма силен указател към този нов екземпляр и той се унищожава.В предишното решение, за да избегнете загубата на екземпляра поради липса на силен указател, запазете статичен масив от текущите екземпляри на
Blocker
и ги изтрийте в метода за обратно извикване на делегат. Отново, това решение работи, но е твърде сложно.
-methodWithDelegate
, тъй като всичко във вашия примерен код връщаvoid
. - person Jonathan Grynspan   schedule 30.01.2013