【问题标题】:How can I cast my NSURLSessionDownloadTask to my custom NSURLSessionDownloadTask (inheritance)?如何将我的 NSURLSessionDownloadTask 转换为我的自定义 NSURLSessionDownloadTask(继承)?
【发布时间】:2014-12-08 02:45:11
【问题描述】:

我创建了一个名为 VJSessionTask 的自定义 NSURLSessionDownloadTask,并且我刚刚添加了一些自定义内容,例如 type (enum)自定义对象(id)

@interface VJSessionTask : NSURLSessionDownloadTask

typedef enum    types
{
    LS, LSH, DL, UL, RM, TH

}               type;

@property enum types type;

@property (strong, nonatomic) id customObject;

@property (strong, nonatomic) NSString *progressNotif;
@property (strong, nonatomic) NSString *doneNotif;

@property (strong, nonatomic) NSURL *tmpFile;

@end

当我这样做时:

VJSessionTask *taskSession = (VJSessionTask *)[self.prioritySession downloadTaskWithRequest:listFileRequest];
// init taskSession with its type
taskSession.type = LS;

我收到此错误:

-[__NSCFLocalDownloadTask setType:]: unrecognized selector sent to instance 0x1556198f0

然后我来找你,因为我不明白或者我不知道该怎么做...... 提前谢谢你;)

【问题讨论】:

  • 强制转换不会改变 downloadTaskWithRequest 实际实例化的对象类型。它只告诉编译器您认为它是什么类(从而控制您可能会或可能不会收到的编译时错误/警告)。因此,尽管有你的演员,标准的downloadTaskWithRequest 仍然实例化NSURLSessionDownloadTask
  • 好的!我明白了,谢谢@Rob ;)

标签: objective-c inheritance casting nsurlsession


【解决方案1】:

不幸的是,NSURLSessionTasks 严格来说不是子类化的。这一点很明显,系统可以对数据任务进行排队并返回一个 NSCFLocalDownloadTask(大概意味着该任务将从缓存中返回其内容)。

执行此操作的最佳方法是借鉴 AFNetworking 的架构决策,并使用单独的 taskDelegates 来监控单个任务的所有响应。然后,当您想查找与任务相关的数据时,您可以查询您的 taskDelegates 字典。每个任务都有一个唯一的标识符,您可以使用它来键入您的字典。

在AFNetworking中可以看到taskDelegate的定义如下:

@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
@property (nonatomic, weak) AFURLSessionManager *manager;
@property (nonatomic, strong) NSMutableData *mutableData;
@property (nonatomic, strong) NSProgress *progress;
@property (nonatomic, copy) NSURL *downloadFileURL;
@property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading;
@property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler;
@end

@implementation AFURLSessionManagerTaskDelegate

随后检索如下:

- (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task {
    NSParameterAssert(task);

    AFURLSessionManagerTaskDelegate *delegate = nil;
    [self.lock lock];
    delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)];
    [self.lock unlock];

    return delegate;
}

更多信息请见this post

【讨论】:

  • 我刚刚有了一个想法,我觉得使用 objc_setAssociatedObject 是个好主意?如果是,我怎样才能保留我的关联对象?
  • 否则,我可以向这个 NSURLSessionDownloadTask 添加自定义属性吗?
  • @Kerosene 你不能子类化任务来添加任何属性并且使用 objc 运行时应该是你真正了解运行时的最后手段
  • 但它肯定会解决您的问题,同时完全忽略整体架构:)
  • 好的,那么,你认为对我来说最简单的解决方案是创建一个 NSMutableDictionnary 并在 task.taskIdentifier 索引处添加 我的任务每次我创建一个?要检索与此任务相关的数据,我在我的字典中搜索?
猜你喜欢
  • 1970-01-01
  • 2013-04-01
  • 2014-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多