我对块的第一个实验给了我EXC_BAD_ACCESS,我不明白为什么

时间:2012-01-17 10:46:52

标签: objective-c ios exc-bad-access objective-c-blocks

- 你好,正如标题所说。我有一个下载程序类,我想用它来降低内容。我以为我尝试使用块来通知调用者下载已完成。从处理.net Web服务的单例类调用startWithRequest方法。我将completionBlock存储在一个实例变量中,然后在下载完成后再调用它。它给了我EXC_BAD_ACCESS。我试着保留completionBlock它没有帮助。这是代码:

-(void) startWithRequest : (NSURLRequest *) request : (void (^)(NSData *data, NSError *error))_completionBlock {
  completionBlock = _completionBlock;
  if (working) {
    [self cancel];
  }
  working = TRUE;
  canceled = FALSE;

  [Globals ShowNetworkActivity];
  urlConnection = [[NSURLConnection alloc] initWithRequest: request delegate: self];
}

- (void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
  [urlData setLength: 0];
}

- (void) connection:(NSURLConnection *) connection didReceiveData:(NSData *)data
{
  if (!urlData)
  {
    urlData = [[NSMutableData alloc] initWithCapacity: bufferSize];
  }
  [urlData appendData: data];
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
  [Globals HideNetworkActivity];
  self.urlConnection = nil;
  ////////HERE it gives me the error
  if (!canceled) completionBlock(urlData, nil);
  self.urlData = nil;
  working = FALSE;
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
  [Globals HideNetworkActivity];
  self.urlConnection = nil;
  self.urlData = nil;

  if (!canceled) completionBlock(nil, error);
  working = FALSE;
}

-(void) cancel
{
  if (working) {
    canceled = TRUE;
    [urlConnection cancel];
    [Globals HideNetworkActivity];
    self.urlConnection = nil;
    self.urlData = nil;
    working = FALSE;
  }
}

感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

您需要复制块,而不是保留它。

没有多少保留将保存在堆栈上实例化的块,因为它的存储将在退出时定义它的函数后立即消失。

-(void) startWithRequest : (NSURLRequest *) request : (void (^)(NSData *data, NSError *error))_completionBlock {
    completionBlock = [_completionBlock copy];

// etc