我有一个类,从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
我相对较晚接触Objective-C(只生活在ARC时代,并且仍在努力理解块),承认我的内存管理理解方面有些薄弱。
这段代码似乎工作正常,但只有当我的代理是strong时才有效。我了解到我的代理应该是weak
以避免潜在的保留循环。查看仪器后,发现进一步的调用不会导致分配增长。然而,我相信'最佳实践'是要有弱引用的代理。
问题
Q1)是否可以使用 strong 代理?
Q2)如何实现基于块的包装器,同时将基础类的代理作为 weak
代理(即,在*delegateBlock接收协议方法之前防止其被释放)?