阻止 NSOPeration 子类在设备中崩溃,但不在模拟器中崩溃

发布于 2025-01-05 17:08:02 字数 2127 浏览 4 评论 0原文

我已经在这段代码上苦苦挣扎了一段时间,我只是不知道为什么在设备中运行时会发生这种情况......应用程序崩溃并出现 EXC_BAD_ACCESS 错误,但在设备中运行时模拟器运行正常。

场景: NSOperation 的子类,与 NSURLConnection 建立异步连接并获取自定义数据。完成后,它会调用带有下载数据的块。

这是 .h 文件:

@interface FileDownloader : NSOperation <NSURLConnectionDataDelegate>

typedef void (^CompletionBlockForFile)(NSData *);

- (id)initWithCompletionBlock:(CompletionBlockForFile)block;

@end

和 .m 文件:

@interface FileDownloader ()

@property (strong, nonatomic) CompletionBlockForFile completionBlock;

@property (strong, nonatomic) NSMutableData *downloadedData;

- (void)downloadFileWithCompletionBlock:(CompletionBlockForFile)block;

@end


@implementation FileDownloader

@synthesize downloadedData = _downloadedData;
@synthesize completionBlock = _completionBlock;

- (id)initWithCompletionBlock:(CompletionBlockForFile)block
{
    self = [super init];
    if (self) {
        _completionBlock = block;
    }
    return self;
}

- (void)main
{
    if (self.isCancelled) return;
    if (_completionBlock) {
        [self downloadFileWithCompletionBlock:_completionBlock];
    }
}

- (void)downloadFileWithCompletionBlock:(CompletionBlockForFile)block
{   
    NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    dispatch_async(dispatch_get_main_queue(), ^{
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
        [connection start];
    });
}

... delegate methods of NSURLConnection

@end

最后,将操作对象添加到 MainViewController 类的队列中的方法:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    FileDownloader *fileDownloader = [[FileDownloader alloc] initWithCompletionBlock:^(NSData *data){      // <----- HERE IS THE EXC_BAD_ACCES ERROR JUST WHEN RUNNING IN THE DEVICE !!! :S
        NSLog(@"%@", data);
    }];

    [queue addOperation:fileDownloader];
}

有人能解释一下我做错了什么吗?在属性中为块变量设置强是否正确?为什么不分配?还是弱?

提前致谢 :)

I have been struggling with this piece of code for a while and I just don't know why it happens that when running in the device ... the app crashes with an EXC_BAD_ACCESS Error but when running in the simulator it runs fine.

The scenario: A subclass of NSOperation that makes an async connection with NSURLConnection and gets custom data. When finished, it calls the block with the downloaded data.

Here is the .h file:

@interface FileDownloader : NSOperation <NSURLConnectionDataDelegate>

typedef void (^CompletionBlockForFile)(NSData *);

- (id)initWithCompletionBlock:(CompletionBlockForFile)block;

@end

and the .m file:

@interface FileDownloader ()

@property (strong, nonatomic) CompletionBlockForFile completionBlock;

@property (strong, nonatomic) NSMutableData *downloadedData;

- (void)downloadFileWithCompletionBlock:(CompletionBlockForFile)block;

@end


@implementation FileDownloader

@synthesize downloadedData = _downloadedData;
@synthesize completionBlock = _completionBlock;

- (id)initWithCompletionBlock:(CompletionBlockForFile)block
{
    self = [super init];
    if (self) {
        _completionBlock = block;
    }
    return self;
}

- (void)main
{
    if (self.isCancelled) return;
    if (_completionBlock) {
        [self downloadFileWithCompletionBlock:_completionBlock];
    }
}

- (void)downloadFileWithCompletionBlock:(CompletionBlockForFile)block
{   
    NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    dispatch_async(dispatch_get_main_queue(), ^{
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
        [connection start];
    });
}

... delegate methods of NSURLConnection

@end

And Finally, the method that adds the operation object to the queue at the MainViewController Class:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    FileDownloader *fileDownloader = [[FileDownloader alloc] initWithCompletionBlock:^(NSData *data){      // <----- HERE IS THE EXC_BAD_ACCES ERROR JUST WHEN RUNNING IN THE DEVICE !!! :S
        NSLog(@"%@", data);
    }];

    [queue addOperation:fileDownloader];
}

Can anybody explain me what am I doing wrong? And is it correct to put strong for the block var in the property? Why not assign? Or weak ?

Thanks in advance :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心头的小情儿 2025-01-12 17:08:02

块应该被复制而不是保留。
更改

@property (**strong**, nonatomic) CompletionBlockForFile completionBlock;

@property (**copy**, nonatomic) CompletionBlockForFile completionBlock;

,它应该可以工作

Blocks should be copied and not retained.
Change

@property (**strong**, nonatomic) CompletionBlockForFile completionBlock;

to

@property (**copy**, nonatomic) CompletionBlockForFile completionBlock;

and it should work

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文