从我的ApplicationDelegate中,我正在通过网络进行NSURLConnection获取(它被包装在一个类中,如下所示)。这个似乎工作正确:我得到所有的数据在didReceiveData和我得到完成调用connectionDidFinishLoading。在connectionDidFinishLoading的末尾,我实例化了一个或多个稍微不同的包装器类,但它们本质上是一样的。问题是第二个NSURLConnection的委托从来没有调用过它的方法。
我看过很多不同的答案,但都没有用。我没有产生任何新的线程,所有的[NSThread isMainThread]检查我已经在整个代码中散落返回true。
我难住了。有人能帮我吗?以下是相关代码:
应用程序委托:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
ConnectionWrapper* w = [[ConnectionWrapper alloc] initWithParams:self
url:[NSURL URLWithString:<url>]];
[w beginFetch];
return YES;
}
...
-(void)fetchCompleted:(NSURL*)url directory:(NSString*)directory
{
NSLog(@"fetch completed");
}
-(void)fetchFailed:(NSURL*)url
{
NSLog(@"fetch failed");
}
...
ConnectionWrapper:
-(id)initWithParams:(id<ConnectionWrapperDelegate>)d url:(NSURL*)url
{
delegate = d;
connURL = url;
return [self init];
}
-(void)beginFetch
{
NSURLRequest* request = [[NSURLRequest alloc] initWithURL:connURL];
NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn release];
[request release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"append");
[responseData appendData:data];
}
- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
... parsing ....
DifferentConnectionWrapper* w = [[DifferentConnectionWrapper alloc] initWithParams:self
url:[NSURL URLWithString:<different url>]];
[w beginFetch];
}
-(void)fetchCompleted:(NSURL*)URL
{
NSLog(@"completed: %@", URL);
}
-(void)fetchFailed:(NSURL*)URL
{
NSLog(@"failed");
}
DifferentConnectionWrapper:
(id) initWithParams: (id) d url: (NSURL *)的url{Delegate = d;
connURL = url;
return [self init];
}
-(void)beginFetch
{
NSURLRequest* request = [[NSURLRequest alloc] initWithURL:connURL];
NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn release];
[request release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"append");
[responseData appendData:data];
}
- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
... parsing ....
DifferentConnectionWrapper* w = [[DifferentConnectionWrapper alloc] initWithParams:self
url:[NSURL URLWithString:<different url>]];
[w beginFetch];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"got response");
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"got data");
[responseData appendData:data];
}
- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
NSLog(@"image saver completed: %@", connURL);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"error");
}
ConnectionWrapper和DifferentConnectionWrapper具有类似的功能,但为了简洁起见,我在这里省略了其他逻辑。
谢谢你的帮助。我很感激。
几件事:我没有看到一个didFailWithError:在你的第一个包装器类,和(有点偏离主题)你泄漏内存与你的DifferentConnectionWrapper *w ?
无论如何,我要尝试的是:看看你是否可以调用DifferentConnectionWrapper直接从appDelegate而不是ConnectionWrapper。在任何情况下,我都会尝试解耦这两个调用。当第一个完成并调用appDelegate时,你不能从那里启动你的DifferentConnectionWrapper吗?
我知道这并不能解释你的问题,但是你可以让它工作(这两件事哪个更重要,是完全不同的争论。)
我认为问题是你在-beginFetch
中释放URL连接:
-(void)beginFetch
{
NSURLRequest* request = [[NSURLRequest alloc] initWithURL:connURL];
NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn release];
[request release];
}
URL连接对象应该保持活动状态,并在连接完成加载时释放:
- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
... parsing ....
// *** Release the connection and whatever data you’ve kept related to
// this particular connection
[connection release];
[responseData release];
// *** or [responseData setLenght:0]; depending on how you’re
// managing responseData
DifferentConnectionWrapper* w = [[DifferentConnectionWrapper alloc] initWithParams:self
url:[NSURL URLWithString:<different url>]];
[w beginFetch];
}
或出现错误时:
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
// *** Release the connection and whatever data you’ve kept related to
// this particular connection
[connection release];
[responseData release];
// *** or [responseData setLenght:0]; depending on how you’re
// managing responseData
// inform the user
NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
编辑:你的初始化器有点奇怪:
-(id)initWithParams:(id<ConnectionWrapperDelegate>)d url:(NSURL*)url
{
delegate = d;
connURL = url;
return [self init];
}
没有办法知道发生了什么,除非我们看到-init
的代码,无论如何,这应该是指定的初始化器,所以它不应该将-init
发送到self
。此外,您应该保留传递给初始化器的url
对象。
下面更有意义:
-(id)initWithParams:(id<ConnectionWrapperDelegate>)d url:(NSURL*)url
{
self = [super init];
if (self) {
delegate = d;
connURL = [url retain];
}
return self;
}
不要忘记在-dealloc
中释放url
对象,或者当你给connURL
赋另一个值时。
OK。事实证明,这个bug是由我遗漏的东西引起的。在第二次请求之后,我就陷入了困境,这可能会把任何事情都搞砸。一旦我解决了这个问题,一切都正常了。
谢谢你的帮助