如何引用类的方法

时间:2014-02-26 16:00:00

标签: ios objective-c properties afnetworking

我正在编写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

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
        }
    });
}

2 个答案:

答案 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];