我正在编写一个 App.net 客户端并使用 ADNKit 作为与 ADN 服务器通信的框架。我从 Zephyr 的开源代码中得到了一些想法。 ,一个变成开源项目的 app.net 客户端。
用于显示帖子列表的 View Controller (PostStreamViewController) 使用数据控制对象和配置对象,该对象具有名为 apiCallMaker
的属性。
属性定义如下:
typedef void (^APIPostListCallback)(NSArray *posts, PostListMetadata *meta, NSError *error);
...
@property (nonatomic, copy) void (^apiCallMaker)(APIPostParameters *parameters, APIPostListCallback callback);
这允许他们在主时间线、提及时间线等中重用相同的数据 Controller 对象。他们所需要做的就是为每种后期流类型提供一个配置文件,每个类型引用不同的 api 调用。
例如,在提及帖子流的配置文件中,他们这样定义 self.apiCallMaker:
- (void (^)(APIPostParameters *parameters, APIPostListCallback callback))apiCallMaker
{
return [^(APIPostParameters *parameters, APIPostListCallback callback) {
[APIUserMentionStream getUserMentionStreamWithParameters:parameters userID:self.userID completionHandler:callback];
} copy];
}
这变得冗长,但坚持我的看法。我觉得这个方法很酷,它使数据 Controller 对象更轻,配置文件也很简单。
在我的实现中,我改为像这样声明我的 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
}
});
这样做的问题是,当我调用 [client fetchPostsMentioningUser:self.user finish:callback] 时,我无法存储对 ANKClient 对象返回的
通过 ANKJSONRequestOperation
的引用;apiCallMaker
。我想存储对 ANKJSONRequestOperation
的引用,因为当我的 View Controller 弹出/解除分配时,我可以轻松取消网络请求。
- (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 *
。
我忘了说我在数据 Controller 上也有一个属性,就像配置文件一样。这有点多余,但是在初始化数据 Controller 时,我将其 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);
配置.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
}
});
}
最佳答案
Configuration.m 中属性 getter 的实现应该是:
- (ANKJSONRequestOperation *(^)(ANKClient *client, APIPostListCallback callback))fetcher
{
return [^(ANKClient *client, APIPostListCallback callback) {
return [client fetchUnifiedStreamForCurrentUserWithCompletion:callback];
} copy];
}
关于ios - 如何引用类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22046678/