NSURLSession委托:如何相应地实现我的自定义SessionDelegate类? [英] NSURLSession delegation: How to implement my custom SessionDelegate class accordingly?

查看:191
本文介绍了NSURLSession委托:如何相应地实现我的自定义SessionDelegate类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个单例类,所谓的RequestManager,它将处理由我的应用程序的不同模块和后台任务发出的请求。

Got a singleton class, so called RequestManager, which shall handle requests made by different modules and background tasks of my application.

@interface RequestFactory : NSObject

- (void)requestDataWith:(NSString *)token
                     id:(NSString *)id
                 sender:(id<RequestFactoryDelegate>)sender;
...

@end

然后我得到另一个class,所谓的SessionDelegate,它将处理请求期间的所有回调。

Then I got another class, so called SessionDelegate, which shall handle all the callbacks during the request.

@interface SessionDelegate : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>

@property (weak, nonatomic) id <RequestFactoryDelegate> delegate;

@end

我的想法是将这些类中的函数封装到不要重载我的类,因为我需要很多辅助类与CommonCrypto等等。

My idea is to encapsulate the functions in these classes to not overload my classes, because I need a lot of helper classes with CommonCrypto and so on.

所以我设置快速编码协议RequestFactoryDe​​legate将接收的数据发送给发送者谁发起了原始请求。

So I set quickly coded a protocol RequestFactoryDelegate to send the received data to the sender who initiated the origin request.

- (void)requestDataWith:(NSString *)token
                     id:(NSString *)id
                 sender:(id<RequestFactoryDelegate>)sender
{
    self.sessionDelegate.delegate = sender;

    NSMutableURLRequest *request = //create the request here

    NSURLSessionDataTask *dataTask = [self.defaultSession dataTaskWithRequest:request];
   [dataTask resume];
}

嗯,如果我有一个对象,我们可以称之为senderA发送请求,因为set delegate总是senderA本身。

Well, it works if I have an object, let us call it senderA which sends the requests, because the set delegate is always senderA itself.

问题出现了另一个对象,例如senderB发送请求 - 甚至不是在同一时间 - 但在senderA发送后不久。

The problem occurs having another object, e.g. senderB which sends requests - not even at the same time - but very shortly after senderA send.

- (void)foo
{
    [requestFactory requestDataWith:token
                                 id:id
                             sender:senderA]; // let's assume this takes 20s

    [requestFactory requestDataWith:token
                                 id:id
                             sender:senderB]; // let's assume this takes 1s
 }

因为senderA的请求仍在进行中,senderB将委托设置给他,发生的事情是senderB的委托函数运行两次。

Because the request of senderA is still in progress, senderB sets the delegate to him and what happens is the delegate function of senderB is run twice.

 <senderB>
 <senderB>

嗯......我真的需要实现一个自己的自定义委托(无论是否在同一个类中作为RequestFactory或不),但如何处理回调方法,以便我可以正确响应senderA或senderB?

Well... I really need to implement an own custom delegate (whether or not in the same class as the RequestFactory or not), but how to I handle the callback methods so I can respond properly to either senderA or senderB?

我的最后一个想法是覆盖NSURLSessionTasks类并实现自己的委托属性或块属性或其他。

My last idea is to override the NSURLSessionTasks class and implement an own delegate property or block property or whatever.

非常感谢提前。

推荐答案

在Objective-C中,您可以在此处找到子类化的替代方法:关联对象

In Objective-C, there is an alternative to subclassing that might be what you want here: associating objects.

它的工作方式如下:您可以使用自定义键将对象附加(关联)到另一个对象,然后再检索它。所以在你的情况下,你会做类似的事情:

It works like this: you can "attach" (associate) an object to another object with a custom key and later retrieve it. So in your case, you would do something like:

#include <objc/runtime.h>

// Top level of your .m file. The type and content of this
// variable don't matter much, we need the _address_ of it.
// See the first link of this answer for details.
static char kDelegateKey = 'd';

- (void)requestDataWith:(NSString *)token
                     id:(NSString *)id
                 sender:(id<RequestFactoryDelegate>)sender
{
    NSMutableURLRequest *request = //create the request here

    NSURLSessionDataTask *dataTask = [self.defaultSession dataTaskWithRequest:request];

   // Associate the sender with the dataTask. We use "assign" here
   // to avoid retain cycles as per the delegate pattern in Obj-C.
   objc_setAssociatedObject(dataTask, &kDelegateKey, sender, OBJC_ASSOCIATION_ASSIGN);

   [dataTask resume];
}

- (void)someOtherMethodWithDataTask:(NSURLSessionDataTask *)dataTask
{
    // Read the attached delegate.
    id<RequestFactoryDelegate> delegate = objc_getAssociatedObject(dataTask, &kDelegateKey);

    // Do something with the delegate.
}

这篇关于NSURLSession委托:如何相应地实现我的自定义SessionDelegate类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆