Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS/Objective-C:如何混合委派和区块?_Ios_Objective C_Delegates_Objective C Blocks - Fatal编程技术网

iOS/Objective-C:如何混合委派和区块?

iOS/Objective-C:如何混合委派和区块?,ios,objective-c,delegates,objective-c-blocks,Ios,Objective C,Delegates,Objective C Blocks,我有两节课Delegator使用委托发送其结果阻止程序在静态方法中使用块 在不更改Delegator的情况下,我如何才能优雅而轻松地实现methodWithBlock,以便使用methodWithDelegate生成的结果调用块 委托人: @class Delegator; @protocol Delegate <NSObject> - (void)delegator:(Delegator *)sender producedResult:(int)result; @end @in

我有两节课
Delegator
使用委托发送其结果<代码>阻止程序在静态方法中使用块

在不更改
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
探索解决方案:

@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
    的当前实例的静态数组,并在委托回调方法中删除它们。同样,此解决方案可行,但过于复杂


使用可观察属性来传达结果,而不是委托和块属性。它更干净(更容易),因为工作对象不必担心它的小脑袋会被谁盯着。监视对象不必担心是否符合任何特殊协议

优雅而简单的解决方案是只需将基于块的方法添加到您的
委托器中即可(例如,通过类别)。我知道你说过你不能这样做,但是我们必须承认,任何其他基于块的解决方案,如果你正在创建新的类来产生你想要的效果,都不能通过优雅测试


话虽如此,如果您迫切需要基于块的方法,并且无法扩展
Delegator
,那么我会倾向于选项2,除了不制作那些类方法,而是制作它们的实例方法,并让
Blocker
实例化
Delegator
并定义包装器方法,以便原本使用
Delegator
的类现在可以使用
Blocker
,但使用
completion
块而不是委托回调。以前实例化
Delegator
的类现在可以实例化
Blocker

我不确定在这种情况下是否可以避免复杂性。我会选择第三个,如果实施得当,它应该是一个赢家。不要害怕复杂的事情:)你从
-methodWithDelegate
返回的结果并不清楚,因为示例代码中的所有内容都返回
void
。我不完全确定我是否理解这个问题,但我很确定如果我理解了,我可以帮你解决问题。Blocker使用静态函数计算内容,然后通过块发送结果。您可以这样调用这些函数:[Blocker methodWithBlock:^(int result){…对result执行任何操作…}];,有什么问题吗?你丢失了什么参考资料?@Ismael:我正在尝试用Block方法实现MethodWithMethod。是的。苹果似乎正朝着这个方向前进,在对象(如NSOperationQueue)中传递状态,并为您实际想要介入和更改/扩展功能而不需要子类化时保留委派。