首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在NSOperation中创建异步NSURLConnection?

如何在NSOperation中创建异步NSURLConnection?
EN

Stack Overflow用户
提问于 2009-08-20 07:24:39
回答 1查看 15.7K关注 0票数 18

我想在后台线程的NSOperation中做一个异步NSURLConnection。

(这是因为我正在对返回的数据执行一些非常昂贵的操作,这些操作希望在数据传入和后台进行时进行。)

这是我的第一次尝试:

在我的AppDelegate中:

代码语言:javascript
复制
// create the opperation and add it to the queue:
self.sharedOperationQueue = [[[NSOperationQueue alloc] init] autorelease];
LibXMLOperation *op = [[[LibXMLOperation alloc] init] autorelease];
[self.sharedOperationQueue addOperation:op];

下面是我的操作:

代码语言:javascript
复制
@interface EbirdLibXMLOperation : NSOperation {
@private
  NSURLConnection *urlConnection;
 // Overall state of the parser, used to exit the run loop.
 BOOL done;
 // properties to maintain the NSOperation
 BOOL finished;
 BOOL executing;  
}
- (void)downloadAndParse:(NSURL *)url;
- (void)start;
- (BOOL)isConcurrent;
- (BOOL)isFinished;
- (BOOL)isExecuting;

@property BOOL done;
@property (nonatomic, retain) NSURLConnection *ebirdConnection;
// The autorelease pool property is assign because autorelease pools cannot be retained.
@property (nonatomic, assign) NSAutoreleasePool *downloadAndParsePool;

@end


@implementation LibXMLOperation
@synthesize urlConnection, done;

- (void)start{
  if (![self isCancelled]) {
    [self willChangeValueForKey:@"isExecuting"];
    executing = YES;
    //set up the thread and kick it off...
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    NSURL *url = [NSURL URLWithString:@"http://google.com"];
    [NSThread detachNewThreadSelector:@selector(downloadAndParse:) toTarget:self withObject:url];
    [self didChangeValueForKey:@"isExecuting"];
  } else {
    // If it's already been cancelled, mark the operation as finished.
    [self willChangeValueForKey:@"isFinished"];
    finished = YES;
    [self didChangeValueForKey:@"isFinished"];
  }
}

- (BOOL)isConcurrent {
  return YES;
}

- (BOOL)isExecuting {
  return executing;
}

- (BOOL)isFinished {
  return finished;
}


- (void)downloadAndParse:(NSURL *)url {
  self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
  done = NO;
  self.characterBuffer = [NSMutableData data];
  [[NSURLCache sharedURLCache] removeAllCachedResponses];
  NSURLRequest *theRequest = [NSURLRequest requestWithURL:url];
  urlConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
  if (urlConnection != nil) {
    do {
      [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    } while (!done);
  }
  [self willChangeValueForKey:@"isFinished"];
  [self willChangeValueForKey:@"isExecuting"];
  finished = YES;
  executing = NO;
  // Clean up.
  self.urlConnection = nil;
  [downloadAndParsePool release];
  NSLog(@"download and parse cleaning up");
  self.downloadAndParsePool = nil;
  [self didChangeValueForKey:@"isExecuting"];
  [self didChangeValueForKey:@"isFinished"];  
}


#pragma mark NSURLConnection Delegate methods

// Disable caching so that each time we run this app we are starting with a clean slate.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
  return nil;
}

// Forward errors to the delegate.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
  done = YES;
}

// Called when a chunk of data has been downloaded.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
  // Process the downloaded chunk of data.
  NSLog(@"Did received %i bytes", [data length]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  // Set the condition which ends the run loop.
  done = YES; 
}    

@end

运行此命令时,我在日志中看到以下消息:

代码语言:javascript
复制
2009-08-20 15:18:48.858 App[1001:3e03]*** _NSAutoreleaseNoPool(): Object 0x1126a20 of class NSCFArray autoreleased with no pool in place - just leaking
Stack: (0x305a2e6f 0x30504682 0x3057deba 0x305ced09 0x30577ddf 0x3056b43e 0x3050764a 0x58fc3 0x3050a79d 0x3050a338 0x94568155 0x94568012)

这个事件在最后一次发生时发生:@“isFinished”;这表明我设置的NSOperation是错误的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-08-20 07:44:45

移动线条:

代码语言:javascript
复制
[downloadAndParsePool release];
self.downloadAndParsePool = nil;

添加到-downloadAndParse:方法的末尾。

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

https://stackoverflow.com/questions/1304508

复制
相关文章

相似问题

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