在NSURLConnection的didReceiveData:
方法中使用appendData:
时遇到的奇怪问题,通常与数据拼接的线程安全性或内存管理有关。以下是可能的原因、解决方案及示例代码:
didReceiveData:
是NSURLConnectionDelegate
的回调方法,用于接收分块数据。开发者通常会在该方法中通过NSMutableData
拼接数据:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.receivedData appendData:data]; // 可能出问题的操作
}
didReceiveData:
可能在后台线程调用,而NSMutableData
不是线程安全的。EXC_BAD_ACCESS
)或数据丢失。receivedData
属性可能被意外释放(如未用strong
修饰)。receivedData
,导致多次请求的数据混合。使用@synchronized
或GCD队列保证线程安全:
@property (atomic, strong) NSMutableData *receivedData;
// 或
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
@synchronized (self) {
[self.receivedData appendData:data];
}
}
在请求开始时重置receivedData
:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
self.receivedData = [NSMutableData new]; // 初始化或清空
}
避免内存溢出,改用文件流:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
[fileHandle seekToEndOfFile];
[fileHandle writeData:data];
[fileHandle closeFile];
}
确保receivedData
为strong
:
@property (nonatomic, strong) NSMutableData *receivedData;
NSURLSession
的downloadTask
。升级到NSURLSession
,其更现代且自动处理线程安全:
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// 数据一次性返回,无需拼接
}];
[task resume];
问题根源多为线程或内存管理,通过加锁、正确初始化或升级API可解决。若需进一步调试,可检查崩溃日志或启用僵尸对象检测(Zombie Objects)。
没有搜到相关的文章