ios - 如何引用类的方法

标签 ios objective-c properties afnetworking

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

配置.h
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/

相关文章:

ios - 清除 iOS 应用程序中的屏幕堆栈

ios - 在 ios sdk 中为电子商务应用程序等任何产品付款的流程?

ios - Monotouch 获取 UiPickerView 选中项

objective-c - Swift 中的CharacterAtIndex

python - 理解 Python 中的属性

java - Spring Java 配置。配置文件中PropertiesFactoryBean的使用

ios - 如何删除文件 Xcode 的引用?

objective-c - Xcode 项目如何以编程方式检测目标或如何使用环境变量

iphone - 如何在 objective-c 中声明指针数组

java - Spring 属性加载 - 动态解密加密属性