我正在编写App.net客户端并使用ADNKit作为与ADN服务器通信的框架。我从Zephyr的开源代码中得到了一些想法,这个app.net客户端已经变成了一个开源项目。
用于显示帖子列表的视图控制器(PostStreamViewController)使用数据控制对象和具有名为apiCallMaker
的属性的配置对象。
属性定义如下:
typedef void (^APIPostListCallback)(NSArray *posts, PostListMetadata *meta, NSError *error);
...
@property (nonatomic, copy) void (^apiCallMaker)(APIPostParameters *parameters, APIPostListCallback callback);
这允许他们为主时间轴重用相同的数据控制器对象,提及时间线等。他们需要做的就是为每个后期流类型提供配置文件,每个类型都引用不同的api调用。
例如,在提及帖子流的配置文件中,他们定义了self.apiCallMaker,如下所示:
- (void (^)(APIPostParameters *parameters, APIPostListCallback callback))apiCallMaker
{
return [^(APIPostParameters *parameters, APIPostListCallback callback) {
[APIUserMentionStream getUserMentionStreamWithParameters:parameters userID:self.userID completionHandler:callback];
} copy];
}
这变得很长,但坚持我。我认为这种方法非常酷,它使得数据控制器对象更轻,配置文件更轻松。
在我的实现中,我改为声明我的apiCallMaker
:
// this is the default parameters returned by ANKClients post fetching methods
typedef void (^APIPostListCallback)(id responseObject, ANKAPIResponseMeta *meta, NSError *error);
...
@property (nonatomic, copy) void (^apiCallMaker)(ANKClient *client, APIPostListCallback callback);
在我的配置文件中,我定义apiCallMaker
,如下所示:
- (void (^)(ANKClient *client, APIPostListCallback callback))apiCallMaker
{
return [^(ANKClient *client, APIPostListCallback callback) {
[client fetchPostsMentioningUser:self.user completion:callback];
} copy];
}
然后在提取帖子时我会这样做:
ANKClient *client = ... // authenticated client object with parameters
self.apiCallMaker(clientCopy, ^(id responseObject, ANKAPIResponseMeta *meta, NSError *error){
if (!error) {
// handle data
} else {
// handle error
}
});
问题在于,当我通过ANKJSONRequestOperation
呼叫[client fetchPostsMentioningUser:self.user completion:callback];
时,我无法存储对ANKClient对象返回的apiCallMaker
的引用。我想将引用存储到ANKJSONRequestOperation
,因为我可以在弹出/取消分配视图控制器时轻松取消网络请求。
- (void)fetchPosts
{
ANKClient *client = ... // authenticated client object with parameters
self.requestOperation = [clientCopy fetchPostsMentioningUser:user completion:^(id responseObject, ANKAPIResponseMeta *meta, NSError *error) {
// handle posts/error
}];
}
...
- (void)dealloc {
...
[self.requestOperation cancel];
}
有没有办法存储对我需要调用的方法(fetchPostsMentioningUser:
)的引用,同时仍然调用客户端对象,以便我可以存储返回的ANKJSONRequestOperation
?
好的,正如@berg所建议的那样,我已经将我的属性的返回类型更改为ANKJSONRequestOperation *
。
我忘了提到我在数据控制器上也有一个属性,就像配置文件一样。这有点多余,但在初始化数据控制器时,我将其apiCallMaker设置为配置中的一个。所以这就是我现在的布局,我已经更改了测试的属性名称。
问题是,每当我设置self.fetcher时,它都是NULL
。我是否需要更改配置文件返回ANKJSONRequestOperation的方式。请原谅我的无知,blocks give me so many headaches。
typedef void (^APIPostListCallback)(id responseObject, ANKAPIResponseMeta *meta, NSError *error);
@property (nonatomic, readonly) ANKJSONRequestOperation *(^fetcher)(ANKClient *client, APIPostListCallback callback);
的 Configuration.m
- (ANKJSONRequestOperation *(^)(ANKClient *client, APIPostListCallback callback))fetcher
{
return [^(ANKClient *client, APIPostListCallback callback) {
[client fetchUnifiedStreamForCurrentUserWithCompletion:callback];
} copy];
}
的 DataController.h
@property (nonatomic, copy) ANKJSONRequestOperation *(^fetcher)(ANKClient *client, APIPostListCallback callback);
的 DataController.m
@property (nonatomic, strong) ANKJSONRequestOperation *operation;
- (id)initWithConfiguration:(Configuration *)configuration {
...
self.fetcher = configuration.fetcher
}
- (void)fetchPosts {
...
self.operation = self.fetcher(clientCopy, ^(id responseObject, ANKAPIResponseMeta *meta, NSError *error) {
if (!error) {
[self.data setPosts:responseObject meta:meta];
} else {
// handle error
}
});
}
答案 0 :(得分:1)
Configuration.m中属性getter的实现应该是:
- (ANKJSONRequestOperation *(^)(ANKClient *client, APIPostListCallback callback))fetcher
{
return [^(ANKClient *client, APIPostListCallback callback) {
return [client fetchUnifiedStreamForCurrentUserWithCompletion:callback];
} copy];
}
答案 1 :(得分:0)
YES。
SEL method = @selector(fetchPostsMentioningUser:);
然后你打电话:
[obj performSelector:method withObject:argument];