如何引用一个类的方法
我正在编写一个App.net客户端,并使用ADNKit作为与ADN服务器通信的框架。 我从Zephyr的一个开源代码中得到了一些想法,这个app.net客户端已经变成了一个开源项目。
他们用于显示post列表(PostStreamViewController)的视图控制器使用一个数据控制对象和一个名为apiCallMaker
的属性的configuration对象。
该属性是这样定义的:
typedef void (^APIPostListCallback)(NSArray *posts, PostListMetadata *meta, NSError *error); ... @property (nonatomic, copy) void (^apiCallMaker)(APIPostParameters *parameters, APIPostListCallback callback);
这允许他们为主时间线重用相同的数据控制器对象,提及时间线等。他们所需要做的就是为每个这样的后置streamtypes提供一个configuration文件,每个types引用不同的api调用。
例如,在提及poststream的configuration文件中,他们像这样定义self.apiCallMaker:
- (void (^)(APIPostParameters *parameters, APIPostListCallback callback))apiCallMaker { return [^(APIPostParameters *parameters, APIPostListCallback callback) { [APIUserMentionStream getUserMentionStreamWithParameters:parameters userID:self.userID completionHandler:callback]; } copy]; }
这是变长了,但坚持我。 我觉得这个方法非常酷,它使得数据控制器对象更轻,configuration文件更简单轻便。
在我的实现中,我反而像这样声明我的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);
在我的configuration文件中,我像这样定义了apiCallMaker
:
- (void (^)(ANKClient *client, APIPostListCallback callback))apiCallMaker { return [^(ANKClient *client, APIPostListCallback callback) { [client fetchPostsMentioningUser:self.user completion:callback]; } copy]; }
然后,当获取post时,我这样做:
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对象返回了这个引用[client fetchPostsMentioningUser:self.user completion:callback];
通过apiCallMaker
。 我想存储对ANKJSONRequestOperation
的引用,因为当我的视图控制器被popup/取消分配时,我可以轻松地取消networking请求。
- (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所build议的那样,我已经将属性的返回types更改为ANKJSONRequestOperation *
。
我忘了提及,我也有一个数据控制器上的属性就像configuration文件。 这是多余的,但是当初始化数据控制器时,我将它的apiCallMaker设置为configuration中的那个。 所以这里是我现在的布局,我已经改变了testing的属性名称。
问题是,每当我设置self.fetcher它是NULL
。 我是否需要更改configuration文件如何返回ANKJSONRequestOperation。 请原谅我的无知, 块给我这么多的头痛 。
Configuration.h
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 } }); }
在Configuration.m中你的属性getter的实现应该是:
- (ANKJSONRequestOperation *(^)(ANKClient *client, APIPostListCallback callback))fetcher { return [^(ANKClient *client, APIPostListCallback callback) { return [client fetchUnifiedStreamForCurrentUserWithCompletion:callback]; } copy]; }
是。
SEL method = @selector(fetchPostsMentioningUser:);
然后你打电话给:
[obj performSelector:method withObject:argument];