Ios NSThread导致iPhone内存泄漏
我上传图像分块,在一个背景线程中,每个分块的大小为512kb,据我所知,我已经使用release、nsautoreleasepool解决了内存泄漏问题。 下面是分块上传图像的代码Ios NSThread导致iPhone内存泄漏,ios,nsthread,Ios,Nsthread,我上传图像分块,在一个背景线程中,每个分块的大小为512kb,据我所知,我已经使用release、nsautoreleasepool解决了内存泄漏问题。 下面是分块上传图像的代码 - (void)FetchDataFromDB : (NSNumber *) isOffline { @autoreleasepool { @try { NSLog(@"FetchDatafromDB"); isThreadStarted = YES; VYukaDBFunction
- (void)FetchDataFromDB : (NSNumber *) isOffline
{
@autoreleasepool {
@try {
NSLog(@"FetchDatafromDB");
isThreadStarted = YES;
VYukaDBFunctions *vdb = [VYukaDBFunctions getInstance];
NSMutableArray *fileNames = [vdb GetFileNames:[isOffline integerValue]];
for(int j=0 ; j<[fileNames count] ; j++)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString * filename = fileNames [j] ;
int _outgoingMsgId = [[vdb SelectMsgId:filename] intValue];
int _totalchunk =[[vdb SelectTotalChunk:filename]intValue];
int currentChunk = [vdb GetCurrentChunk:filename];
for( int i=currentChunk ; i <= _totalchunk ; i++)
{
NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];
NSString *AsyncRequest = [[NSString alloc] init];
AsyncRequest = [vdb SelectAsyncRequest: i : _outgoingMsgId];
if(![AsyncRequest isEqual:@""])
{
BOOL status = [self UploadChunkWise :AsyncRequest : 1 : i : vdb : filename : _outgoingMsgId];
// AsyncRequest = NULL;
// [AsyncRequest release];
if(status){
if(i==_totalchunk)
{
NSLog(@"Deleting from medialist , FileName :%@", filename);
[vdb DeleteFromMediaList : filename];
}
}
else{
[vdb DeleteFromMediaList : filename];
break;
}
}
[innerPool drain];
}
[pool drain];
}
[fileNames removeAllObjects];
// [fileNames release];
//recurssive call to check any pending uploads..
if([[vdb GetFileNames:[isOffline integerValue]] count] > 0)
{
NSLog(@"Calling Recursively..");
[self FetchDataFromDB:[isOffline integerValue]];
}
}
@catch (NSException *exception) {
NSLog(@"Exception caught on Uploading from FetchDataFromDB:%@", exception);
}
@finally {
}
}
NSLog(@"thread quit ");
isThreadStarted = NO;
[NSThread exit];
}
-(BOOL) UploadChunkWise :(NSString *) AsyncRequest : (int) count : (int)currentChunk : (VYukaDBFunctions * ) vdb : (NSString *) currentFileName : (int) outgoingMsgId
{
NSHTTPURLResponse *response ;
NSError *error;
//Yes, http
NSMutableURLRequest *httpRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"Url goes here"]];
NSData* data = [AsyncRequest dataUsingEncoding:NSUTF8StringEncoding];
[httpRequest setHTTPMethod:@"POST"];
[httpRequest setHTTPBody:data];
[httpRequest setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
NSData *returnedData = [NSURLConnection sendSynchronousRequest: httpRequest returningResponse:&response error:&error] ;
NSString *result= [[NSString alloc] initWithData:returnedData encoding:NSASCIIStringEncoding];
[httpRequest release];
returnedData= NULL;
[returnedData release];
data = NULL;
[data release];
if ([result rangeOfString:@"success"].location != NSNotFound )
{
NSLog(@" success");
[vdb DeleteCurrentChunkFromOutgoingTable:currentChunk : outgoingMsgId];
[result release];
return YES ;
}
else if ([result rangeOfString:@"fail"].location != NSNotFound )
{
[result release];
if (count < 3) {
return [self UploadChunkWise :AsyncRequest : count+1 : currentChunk: vdb : currentFileName : outgoingMsgId ];
}
else
{
NSLog(@" failed");
[vdb DeleteAllCurrentFileChunksFromOutgoingTable:currentFileName];
return NO ;
}
}
return NO;
}
问题是在上传了9到12个块之后,我得到了内存错误。我收到4到5次内存警告,之后应用程序崩溃。在控制台中,我首先在应用程序委托类收到内存警告,然后是扩展UIViewController的4个类。为什么我在app delegate和其他UIViewController类型的类上收到警告。如果单独的线程给我内存错误,为什么我必须释放其他类的对象?我做错了什么?我不能使用ARC,因为我已经将它与旧代码集成在一起了,旧代码没有使用ARC,我尝试在类方面启用ARC,但它无法工作。有人能帮我找出这段代码中是否有内存泄漏吗。欢迎提出建议并表示感谢。提前感谢 有两件事-首先,我看到:
NSString *AsyncRequest = [[NSString alloc] init];
AsyncRequest = [vdb SelectAsyncRequest: i : _outgoingMsgId];
这应合并为:
NSString *asyncRequest = [vdb SelectAsyncRequest: i : _outgoingMsgId];
而是创建一个新实例,然后立即生成或引用另一个实例
第二:
您的代码很难阅读,并且不符合Objective-C smalltalk约定
变量名称应以小写字母开头。方法名称也应该以小写字母开头。类名和函数应以大写字母开头。这使得阅读变得困难,因为我和其他许多人都接受过训练,能够看到大写字母,并思考类名而不是可能的变量名。仅供参考
最后,有些方法采用多个参数,如上面的一个。您确实应该为每个参数添加一个前缀,以便容易理解参数的用途。这:
[vdb SelectAsyncRequest: PARAMETER : PARAMETER];
如果它是:
[vdb selectAsyncRequestForParameter: PARAMETER withOtherParameter:OTHERPARAM];
编辑:我也不认为你需要这么多的自动释放池。整个事情已经被包裹在一个大的自动释放池中
EDIT2:我还看到很多不必要的release
调用。在您的UploadChunkWise
方法中,您正在调用已隐式自动删除的*data
和*returnedData
上的release。将对象返回给您的方法将已经放弃所有权并“移交”给您。基本上,这些方法可以做到这一点:
NSData *data = [[NSData alloc] init];
return [data autorelease];
当你得到它时,如果你想保留它,你必须自己保留它,否则它会在你的方法返回时被销毁
但是,对您使用-init
创建的NSString*result
实例调用release是正确的
NSData *data = [[NSData alloc] init];
return [data autorelease];