从 NSOperation 的子类中调用 NSURLSession 方法
Call NSURLSession method from inside the subclass of NSOperation
我的应用程序有 table 带有自定义单元格的视图,其中有:
@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];
}
根本没有加载图像,队列只是进入配置方法而已。请告诉我怎么了?
提前谢谢你。
编辑:
正在更新 UI:
-(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];
});
}
你的class是NSOperation
的子class,不是NSOperationQueue
所以你不能指定它使用self
作为目标队列对于 NSURLSession
对象。坦率地说,您只需使用 nil
作为操作队列参数,因为您不关心委托方法在哪个队列上 运行。或者,如果需要,您可以创建自己的操作队列。但是你不能使用 self
.
但请确保将任何 UI 更新分派回主队列。
此外,您必须将其设为异步 NSOperation
subclass,否则操作将终止并在您的委托方法有机会被调用之前被释放。
作为一个小观察,我建议将此 class 重命名为 MyOperation
,以避免操作和操作队列之间的混淆。
我的应用程序有 table 带有自定义单元格的视图,其中有:
@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];
}
根本没有加载图像,队列只是进入配置方法而已。请告诉我怎么了? 提前谢谢你。
编辑: 正在更新 UI:
-(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];
});
}
你的class是NSOperation
的子class,不是NSOperationQueue
所以你不能指定它使用self
作为目标队列对于 NSURLSession
对象。坦率地说,您只需使用 nil
作为操作队列参数,因为您不关心委托方法在哪个队列上 运行。或者,如果需要,您可以创建自己的操作队列。但是你不能使用 self
.
但请确保将任何 UI 更新分派回主队列。
此外,您必须将其设为异步 NSOperation
subclass,否则操作将终止并在您的委托方法有机会被调用之前被释放。
作为一个小观察,我建议将此 class 重命名为 MyOperation
,以避免操作和操作队列之间的混淆。