блок внутри NSOPeration подкласс сбой в устройстве, но не в симуляторе - PullRequest
1 голос
/ 15 февраля 2012

Я некоторое время боролся с этим фрагментом кода, и я просто не знаю, почему это происходит, когда при работе на устройстве ... приложение вылетает с ошибкой 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];
}

Может кто-нибудь объяснить мне, что я делаю неправильно?И правильно ли ставить сильные для блока var в свойстве?Почему бы не назначить?Или слабый?

Заранее спасибо:)

1 Ответ

1 голос
/ 17 февраля 2012

Блоки должны быть скопированы, а не сохранены. Изменение

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

до

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

и должно работать

...