URL から JSON を取得し、プロトコル/デリゲート パターンを介してデータを返すクラスがあります。
MRDelegateClass.h
#import <Foundation/Foundation.h>
@protocol MRDelegateClassProtocol
@optional
- (void)dataRetrieved:(NSDictionary *)json;
- (void)dataFailed:(NSError *)error;
@end
@interface MRDelegateClass : NSObject
@property (strong) id <MRDelegateClassProtocol> delegate;
- (void)getJSONData;
@end
strong
デリゲート プロパティに使用していることに注意してください。それについては後で詳しく...
ブロックベースの形式で getJSONData を実装する「ラッパー」クラスを作成しようとしています。
MRBlockWrapperClassForDelegate.h
#import <Foundation/Foundation.h>
typedef void(^SuccessBlock)(NSDictionary *json);
typedef void(^ErrorBlock)(NSError *error);
@interface MRBlockWrapperClassForDelegate : NSObject
+ (void)getJSONWithSuccess:(SuccessBlock)success orError:(ErrorBlock)error;
@end
MRBlockWrapperClassForDelegate.m
#import "MRBlockWrapperClassForDelegate.h"
#import "MRDelegateClass.h"
@interface DelegateBlock:NSObject <MRDelegateClassProtocol>
@property (nonatomic, copy) SuccessBlock successBlock;
@property (nonatomic, copy) ErrorBlock errorBlock;
@end
@implementation DelegateBlock
- (id)initWithSuccessBlock:(SuccessBlock)aSuccessBlock andErrorBlock:(ErrorBlock)aErrorBlock {
self = [super init];
if (self) {
_successBlock = aSuccessBlock;
_errorBlock = aErrorBlock;
}
return self;
}
#pragma mark - <MRDelegateClass> protocols
- (void)dataRetrieved:(NSDictionary *)json {
self.successBlock(json);
}
- (void)dataFailed:(NSError *)error {
self.errorBlock(error);
}
@end
// main class
@interface MRBlockWrapperClassForDelegate()
@end
@implementation MRBlockWrapperClassForDelegate
+ (void)getJSONWithSuccess:(SuccessBlock)success orError:(ErrorBlock)error {
MRDelegateClass *delegateClassInstance = [MRDelegateClass new];
DelegateBlock *delegateBlock = [[DelegateBlock alloc] initWithSuccessBlock:success andErrorBlock:error];
delegateClassInstance.delegate = delegateBlock; // set the delegate as the new delegate block
[delegateClassInstance getJSONData];
}
@end
私は比較的最近客観的 c の世界に来ました (ARC の時代にのみ住んでいて、まだブロックと折り合いをつけています)。
このコードは正常に動作するように見えますが、デリゲートがstrong
. weak
私は、リテンション サイクルの可能性を回避するために代理人が必要であることを理解しています。金融商品を調べてみると、コールの継続によって割り当てが増え続けていないことがわかりました。ただし、「ベストプラクティス」はweak
デリゲートを持つことだと思います。
質問
strong
Q1)デリゲートを持つことは「OK」ですか?
Q2) 基になるクラスのデリゲートをデリゲートとして残すブロックベースのラッパーを実装するにはどうすればよいですかweak
(つまり、プロトコル メソッドを受け取る前に *delegateBlock の割り当てが解除されるのを防ぎます)。