从NSOperation的子类内部调用NSURLSession方法

时间:2016-03-30 23:09:42

标签: ios objective-c nsurlsession nsoperation nsoperationqueue

我的应用程序我有自定义单元格的表格视图,其中包含:

@property (weak, nonatomic) IBOutlet UIImageView *image;
@property (weak, nonatomic) IBOutlet UILabel *nameOfImage;
@property (weak, nonatomic) IBOutlet UIButton *start;

我需要异步下载任意数量的图像(按下很多开始按钮)。为此,我创建了NSOperation的子类 - MyOperationQueue。它的实现看起来像这样:

- (id)initWithURL:(NSURL*)url andRaw:(NSInteger)row
{
    if (![super init])
        return nil;
    [self setTargetURL:url];
    [self setCurrentCell:row];
    self.customCell = [[CustomTableViewCell alloc]init];
    self.tableView = [ContentTableView sharedManager];
    return self;
}

- (void)main
{
    if ([self isCancelled])return;
    self.defaultSession = [self configureSession];
    NSURLSessionDownloadTask *task = [self.defaultSession downloadTaskWithURL:self.targetURL];
    if ([self isCancelled])  return;
    [task resume];
 }

- (void)cancel
{
    self.isCancelled = YES;
       if(self.downloadTask.state == NSURLSessionTaskStateRunning)
        [self.downloadTask cancel];
}

在这些方法中我还在这里描述了NSURLSession方法:

    - (NSURLSession *) configureSession //it visits it
    {
 NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self.tableView **delegateQueue:self**];  //self - warning - incompatible pointer type sending "MyOperationQueue" to "NSOperationQueue" _Nullable.

}

-(void)URLSession:(NSURLSession *)session
         downloadTask:(NSURLSessionDownloadTask *)downloadTask
         didWriteData:(int64_t)bytesWritten
    totalBytesWritten:(int64_t)totalBytesWritten
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite // don't visit

-(void)URLSession:(NSURLSession *)session
     downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location    // don't visit

我在TableView中的方法中创建自定义队列:

   - (void)didClickStartAtIndex:(NSInteger)cellIndex withData:(CustomTableViewCell*)data
    {
        NSURL *url = [NSURL URLWithString: tmp.imeageURL];
        MyOperationQueue * one = [[MyOperationQueue alloc]initWithURL:url andRaw:self.selectedCell];
        [self.queue addOperation:one];
    }

根本没有加载图像,队列只是进入配置方法,就是这样。请告诉我什么错了? 提前谢谢。

编辑: 更新用户界面:

-(void)URLSession:(NSURLSession *)session
     downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{
    NSLog(@"didFinishDownloadingToURL - Queue");
    NSData *d = [NSData dataWithContentsOfURL:location];
    UIImage *im = [UIImage imageWithData:d];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.customCell.image.image = im;
        self.customCell.realProgressStatus.text = @"Downloaded";
        [self.tableView.tableView reloadData];
    });
}

1 个答案:

答案 0 :(得分:1)

您的类是NSOperation的子类,而不是NSOperationQueue因此您无法指定它使用self作为NSURLSession对象的目标队列。坦率地说,您只需使用nil作为操作队列参数,因为您不关心委托方法在哪个队列中运行。或者,如果需要,您可以创建自己的操作队列。但是你不能使用self

但请确保将任何UI更新分发回主队列。

此外,您必须使其成为异步NSOperation子类,否则操作将终止并在您的委托方法有机会被调用之前被释放。

作为次要观察,我建议将此类重命名为MyOperation,以避免操作和操作队列之间的混淆。