クラスに次のセレクターがあります。
- (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
}];
これを達成するための最良の方法は何ですか?
更新* *
これはほとんど機能していますが、completionBlock オブジェクトの objc_release で例外が発生しています。ターゲットを保持することと関係があると確信していますが、それを修正する方法がわかりません。現在のコードは次のとおりです。
- (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
助けてくれてありがとう!