作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在一个类中有以下选择器:
- (SoapRequest*) loginAndConnect: (id) target action: (SEL) action credentials: (WSAcredentials*) arg0 dialoutInfo: (WSAdialoutInfo*) arg1;
[service loginAndConnect:self credentials:credentials dialoutInfo:dialoutInfo action:^(SoapRequest* aResult) {
// more code here
}];
- (BOOL) checkService {
WSAcredentials* credentials = [[WSAcredentials alloc] init];
WSAdialoutInfo* dialoutInfo = [[WSAdialoutInfo alloc] init];
if (!service) {
service = [[WSAWebSocketAdapterService alloc] init];
}
__block SoapRequest* request;
[service loginAndConnectWithCredentials:credentials dialoutInfo:dialoutInfo completionBlock:^(SoapRequestCompletionBlock completionBlock) {
request = (SoapRequest*)completionBlock;
if ([request isKindOfClass: [SoapFault class]]) {
return YES; // we got a response, that's all we care about
}
return NO;
}
];
return YES;
}
#import "WSAWebSocketAdapterService+BlockExtension.h"
// These objects serve as targets (with action being completed:) for the original object.
// Because we use one for each request we are thread safe.
@interface MyCustomSoapTargetAction : NSObject
@property (copy) SoapRequestCompletionBlock block;
- (void) completed:(id)sender;
@end
@implementation MyCustomSoapTargetAction
- (void) completed:(id)sender
{
// Assuming 'sender' is your SoapRequest
if (_block != nil)
_block(sender);
_block = nil;
}
@end
@implementation WSAWebSocketAdapterService(BlockExtension)
- (SoapRequest*) loginAndConnectWithCredentials:(WSAcredentials*) arg0
dialoutInfo: (WSAdialoutInfo*) arg1
completionBlock:(BOOL (^)(SoapRequestCompletionBlock))completionBlock
{
MyCustomSoapTargetAction *target = [[MyCustomSoapTargetAction alloc] init];
target.block = (SoapRequestCompletionBlock) completionBlock;
//
// Here we assume that target will be retained.
// If that's not the case then we will need to add it to some collection before
// the call below and have the target object remove itself from it after its
// block has been called.
//
return [self loginAndConnect:target action:@selector(completed:) credentials:arg0 dialoutInfo:arg1];
}
@end
最佳答案
您实际上不需要源代码。一个类别就可以了。这是一些示例代码,可帮助您入门,
这甚至是线程安全的!如果您的对象没有保留目标,那么在调用它的 block 之前还需要做更多的工作来保留它。
// -- TheClassName+BlockExtension.h
typedef void (^SoapRequestCompletionBlock)(SoapRequest*);
@interface TheClassName(BlockExtension)
- loginAndConnectWithCredentials:(WSAcredentials*) arg0
dialoutInfo: (WSAdialoutInfo*) arg1;
completionBlock:(SoapRequestCompletionBlock)completionBlock;
@end
// -- TheClassName+BlockExtension.m
// EDITED: If the 'target' object is not retained by the loginAndConnect... then
// we may add it to this collection. In this implementation, a block can
// only be used once.
static NSMutableSet *gSoapTargets = nil;
// These objects serve as targets (with action being completed:) for the original object.
// Because we use one for each request we are thread safe.
@interface MyCustomSoapTargetAction
@property (copy) SoapRequestCompletionBlock block;
- (void) completed:(id)sender;
@end
@implementation MyCustomSoapTargetAction
- (id) init
{
// Objects adds itself to the global collection
if ((self = [super init]))
[gSoapTargets addObject:self];
return self;
}
- (void) completed:(id)sender
{
// Assuming 'sender' is your SoapRequest
if (_block != nil)
_block(sender);
// Object removes itself from global collection when done.
// On return from this method it will likely be released.
[gSoapTargets removeObject:self];
}
+ (void) load
{
gSoapTargets = [NSMutableSet set];
}
@end
@implementation TheClassName(BlockExtension)
- (SoapRequest*) loginAndConnectWithCredentials:(WSAcredentials*) arg0
dialoutInfo: (WSAdialoutInfo*) arg1;
completionBlock:(SoapRequestCompletionBlock)completionBlock
{
MyCustomSoapTargetAction *target = [[MyCustomSoapTargetAction alloc] init];
target.block = completionBlock;
//
// Here we assume that target will be retained.
// If that's not the case then we will need to add it to some collection before
// the call below and have the target object remove itself from it after its
// block has been called.
//
[self loginAndConnect:target action:@selector(completed:) credentials:arg0 dialoutInfo:arg1];
}
@end
- (BOOL) serviceIsAvailable
{
return _serviceIsAvailable;
}
- (void) _setServiceIsAvailable:(BOOL)value
{
// This method should probably be private thus the _ prefix
// Do something with the result (set some status, warn user...).
_serviceIsAvailable = value;
}
- (void) checkService
{
WSAcredentials* credentials = [[WSAcredentials alloc] init];
WSAdialoutInfo* dialoutInfo = [[WSAdialoutInfo alloc] init];
if (_service == nil)
_service = [[WSAWebSocketAdapterService alloc] init];
[_service loginAndConnectWithCredentials:credentials
dialoutInfo:dialoutInfo
completionBlock:^(id sender)
{
[self _setServiceIsAvailable:[sender isKindOfClass:[SoapFault class]]];
}];
}
关于ios - 如何将目标操作转换为阻止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15712816/
我是一名优秀的程序员,十分优秀!