首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSURLSessionDownloadTask在NSOperation中崩溃

NSURLSessionDownloadTask在NSOperation中崩溃
EN

Stack Overflow用户
提问于 2021-10-25 17:10:13
回答 1查看 43关注 0票数 0

我正在尝试创建一个DownloadOperation子类NSOperation,以便异步下载数据。在我试图加入取消支持之前,一切似乎都很顺利。基本上,操作的NSURLSessionDownloadTask的完成处理程序似乎是在操作发布后调用的。它将与EXC_BAD_ACCESS在行weakSelf.state = kFinished上崩溃。

完整的示例项目如下:https://github.com/angstsmurf/DownloadOperationQueue。按Command+.在跑去撞车之后。

代码语言:javascript
复制
#import "DownloadOperation.h"

typedef enum OperationState : NSUInteger {
    kReady,
    kExecuting,
    kFinished
} OperationState;

@interface DownloadOperation ()

@property NSURLSessionDownloadTask *task;

@property OperationState state;

@end


@implementation DownloadOperation


// default state is ready (when the operation is created)

@synthesize state = _state;

- (void)setState:(OperationState)state {
    @synchronized(self) {
        if (_state != state) {
            [self willChangeValueForKey:@"isExecuting"];
            [self willChangeValueForKey:@"isFinished"];
            _state = state;
            [self didChangeValueForKey: @"isExecuting"];
            [self didChangeValueForKey: @"isFinished"];
        }
    }
}

- (OperationState)state {
    @synchronized (self) {
        return _state;
    }
}

- (BOOL)isReady { return (self.state == kReady); }
- (BOOL)isExecuting { return (self.state  == kExecuting); }
- (BOOL)isFinished { return (self.state  == kFinished); }

- (BOOL)isAsynchronous {
    return YES;
}

- (instancetype)initWithSession:(NSURLSession *)session downloadTaskURL:(NSURL *)downloadTaskURL completionHandler:(nullable void (^)(NSURL * _Nullable,  NSURLResponse * _Nullable,  NSError * _Nullable))completionHandler {

    self = [super init];

    if (self) {
        __unsafe_unretained DownloadOperation *weakSelf = self;
        // use weak self to prevent retain cycle
        _task = [[NSURLSession sharedSession] downloadTaskWithURL:downloadTaskURL
                                                completionHandler:^(NSURL * _Nullable localURL, NSURLResponse * _Nullable response, NSError * _Nullable error) {

            /*
             if there is a custom completionHandler defined,
             pass the result gotten in downloadTask's completionHandler to the
             custom completionHandler
             */
            if (completionHandler) {
                completionHandler(localURL, response, error);
            }

            /*
             set the operation state to finished once
             the download task is completed or have error
             */
            weakSelf.state = kFinished;
        }];
    }

    return self;
}

- (void)start {
    /*
     if the operation or queue got cancelled even
     before the operation has started, set the
     operation state to finished and return
     */
    if (self.cancelled) {
        self.state = kFinished;
        return;
    }

    // set the state to executing
    self.state = kExecuting;

    NSLog(@"downloading %@", self.task.originalRequest.URL.absoluteString);

    // start the downloading
    [self.task resume];
}

-(void)cancel {
    [super cancel];

    // cancel the downloading
    [self.task cancel];
}

@end
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-27 06:52:34

正如Scott在注释中指出的那样,weakSelf变量使用的正确关键字是__weak,而不是__unsafe_unretained

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69712151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档