0

我正在我的 iOS 应用程序的远程服务器上上传包含来自我的应用程序的图像文件夹的 Zip。该函数在单独的 NSThread 中调用,因此它不应阻塞 UI。在这里,我创建了一批包含图像(最大 10 MB)的文件夹,并通过调用远程服务器上的 SP 将它们上传到远程服务器上。问题是每次调用此方法都会增加我的实时字节数,这取决于 zip 文件的大小,而该文件永远不会再下降。贝娄是我的代码:

-(IBAction)syncPressed:(id)sender
{
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *strServerFolderPath = [[paths objectAtIndex:0]stringByAppendingPathComponent:app.objDataAccess.tempServerIPAddress];
NSString *strImagesFolderPath=[strServerFolderPath stringByAppendingPathComponent:@"Images"];
NSString *strDatabaseImagesPath=[strImagesFolderPath stringByAppendingPathComponent:app.objDataAccess.tempDBName];
NSArray *arrOfDirectoryToZip=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:strDatabaseImagesPath error:NULL];
int iZippedFolderCounter=0;

if(app.viewController.arrADataSyncProgress==nil)
    app.viewController.arrADataSyncProgress=[[NSMutableArray alloc]init];
else
    [app.viewController.arrADataSyncProgress removeAllObjects];

unsigned long long int iSizeOfFolder=[app.globalVcImageViewController folderSize:strDatabaseImagesPath];

int iNoOfBatches=iSizeOfFolder/10485760;
if(iSizeOfFolder%10485760>0)
    iNoOfBatches++;       //We will need to add one more batch for remainings

int iCounter=1;
//Add batch objects in array initially so that they can be updated at correct time
while(iCounter<=iNoOfBatches)
{
    SyncProgress *objSync=[[SyncProgress alloc]init];
    objSync.cSyncName=[NSString stringWithFormat:@"Batch %d",iCounter];
    objSync.iSyncStatus=0;
    objSync.cSpName=@"UploadImageData";
    objSync.cStartSyncTime=@" ";
    objSync.cEndTime=@" ";
    [app.viewController.arrADataSyncProgress addObject:objSync];
    objSync=nil;
    iCounter++;
}

[app.viewController.tblviwSyncProgress performSelectorInBackground:@selector(reloadData) withObject:nil];

float fPerBatchIncrement=100.0/iNoOfBatches;

[Flurry logEvent:@"Sync started"];
[app.objLogger writetoLogFileWithMessage:@"Sync started" withMethodName:@"syncPressed:" withLoggerLevel:eLoggerInfo];

int iBatchCounter=0;
//Upload images batchwise
while(iBatchCounter<iNoOfBatches)
{
        NSMutableArray *arrmPathsToZip=nil;
        unsigned long long int iSizeOfBatch=0;
        //In each batch 10 MB or remaining folders are zipped
        while(iZippedFolderCounter<arrOfDirectoryToZip.count && (iSizeOfBatch+[app.globalVcImageViewController folderSize:[strDatabaseImagesPath stringByAppendingPathComponent:[arrOfDirectoryToZip objectAtIndex:iZippedFolderCounter]]])<10485760 && iZippedFolderCounter<arrOfDirectoryToZip.count)
        {
            //Add Paths to temporary array
            if(arrmPathsToZip==nil)
                arrmPathsToZip=[[NSMutableArray alloc]init];

            [arrmPathsToZip addObject:[strDatabaseImagesPath stringByAppendingPathComponent:[arrOfDirectoryToZip objectAtIndex:iZippedFolderCounter]]];
            iSizeOfBatch+=[app.globalVcImageViewController folderSize:[strDatabaseImagesPath stringByAppendingPathComponent:[arrOfDirectoryToZip objectAtIndex:iZippedFolderCounter]]];

            iZippedFolderCounter++;
        }


        //Give the zip a random unique name
        NSString *strRandomFolderName=[NSString stringWithFormat:@"%f",[[NSDate date] timeIntervalSince1970]];
        NSString *strZipPath= [strImagesFolderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip",strRandomFolderName]];

        //Create zip from the folder
        BOOL bSuccess = [SSZipArchive createZipFileAtPath:strZipPath withContentsOfDirectoris:arrmPathsToZip];
        arrmPathsToZip=nil;

        if(!bSuccess)
        {
            [app removeCustomLoader];
            UIAlertView *altError=[[UIAlertView alloc]initWithTitle:app.strAppName message:@"Error occured while gathering data" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
            [altError show];
            altError=nil;
        }
        else
        {
            //Update sync progress object
            SyncProgress *objSyncProgress=(SyncProgress*)[app.viewController.arrADataSyncProgress objectAtIndex:iBatchCounter];
            objSyncProgress.cStartSyncTime = [app.loginView getCurrentTimeInUTCFormatToString];
            [app.viewController.tblviwSyncProgress performSelectorInBackground:@selector(reloadData) withObject:nil];

            NSData *dat=[NSData dataWithContentsOfFile:strZipPath];
            //[Base64 initialize];
            NSString *strZipEncoded = [Base64 encode:dat];
            NSString *cDBToken=app.dbToken;

            //Get Key From GUID
            NSString *cGUID=[app.loginView generateUuidString];
            int iKey = [app.loginView KeyFromGUID:cGUID];

            //Encrypt Parameter
            cDBToken=[app.loginView  encrypt:cDBToken withShiftCount:iKey];
            cDBToken= [NSString stringWithFormat:@"%@##%@",cGUID,cDBToken];
            NSString *strUserName=[app.loginView encrypt:app.LoginUsrnm withShiftCount:iKey];
            NSString *strPassword=[app.loginView encrypt:app.LoginPswd withShiftCount:iKey];
            NSString *strSPName=[app.loginView encrypt:@"_wspIICInsertImages" withShiftCount:iKey];

            //SOAP Request
            NSMutableString *soapMsg =[[NSMutableString alloc] initWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\
                                <soap:Envelope\
                                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\
                                xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\
                                xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\
                                <soap:Body>\
                                <UploadImageData\
                                xmlns=\"http://tempuri.org/\">\
                                <DBToken><![CDATA[%@]]></DBToken>\
                                <UserName><![CDATA[%@]]></UserName>\
                                <Password><![CDATA[%@]]></Password>\
                                <DeviceID>1</DeviceID>\
                                <BatchSize>1</BatchSize>\
                                <DocString><![CDATA[%@]]></DocString>\
                                <fileName><![CDATA[%@]]></fileName>\
                                <SPName><![CDATA[%@]]></SPName>\
                                </UploadImageData>\
                                </soap:Body>\
                                </soap:Envelope>",cDBToken,strUserName,strPassword,strZipEncoded,strRandomFolderName,strSPName];

            NSURL *url = [NSURL URLWithString:app.webServiceName];

            NSMutableURLRequest *req =
            [NSMutableURLRequest requestWithURL:url];

            NSString *msgLength =
            [NSString stringWithFormat:@"%d", [soapMsg length]];

            [req addValue:@"text/xml; charset=utf-8"
       forHTTPHeaderField:@"Content-Type"];

            [req addValue:msgLength
       forHTTPHeaderField:@"Content-Length"];

            //add gzip-encoding to HTTP header
            [req setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];


            [req addValue:@"http://tempuri.org/UploadImageData"
       forHTTPHeaderField:@"SOAPAction"];

            [req setHTTPMethod:@"POST"];
            [req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
            soapMsg=nil;

            [req setTimeoutInterval: 60];

            //call method to connect to webservice by passing request object
            NSURLResponse* urlResponse = nil;
            NSError *error;
            NSData *responseData =  [NSURLConnection sendSynchronousRequest:req returningResponse:&urlResponse error:&error];
            NSString *strResponse=[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
            [[NSFileManager defaultManager] removeItemAtPath:strZipPath error:NULL];

            if(iZippedFolderCounter<arrOfDirectoryToZip.count)
                app.viewController.fPercentageSync=app.viewController.fPercentageSync+fPerBatchIncrement;
            else
                app.viewController.fPercentageSync=100;

            app.viewController.fDataSize+=dat.length/(1024.0*1024);
            dat=nil;

            //Update sync progress object
            objSyncProgress=(SyncProgress*)[app.viewController.arrADataSyncProgress objectAtIndex:iBatchCounter];

            if([[app stringBetweenString:@"<UploadImageDataResult>" andString:@"</UploadImageDataResult>" withstring:strResponse] isEqualToString:@"true"])
            {
                objSyncProgress.iSyncStatus=1;

            }
            else
                objSyncProgress.iSyncStatus=2;

            objSyncProgress.cEndTime=[app.loginView getCurrentTimeInUTCFormatToString];

            [app performSelectorInBackground:@selector(setHUDSubtitle:) withObject:[NSNumber numberWithFloat:app.viewController.fPercentageSync]];
            [app.viewController.tblviwSyncProgress performSelectorInBackground:@selector(reloadData) withObject:nil];

            responseData=nil;
            strResponse=nil;
            strZipEncoded=nil;
        }

        iBatchCounter++;
}
btnSync.selected=NO;
[Flurry logEvent:@"Sync completed"];
[app.viewController.actSyncProgress stopAnimating];
[app removeCustomLoader];
NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
formatter.dateFormat=@"dd-MM-yyyy hh:mm:ss a";
NSString *strSyncCompletionDate=[formatter stringFromDate:[NSDate date]];
[app.objDataAccess insertIntoDatabaseUserName:app.LoginUsrnm syncCompletionTime:strSyncCompletionDate dataSize:app.viewController.fDataSize serverName:app.loginView.tempServerName databaseName:app.loginView.tempDBName];
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
}

对上述函数的调用如下:

[NSThread detachNewThreadSelector:@selector(syncPressed:) toTarget:self withObject:nil];

任何我哪里出错的指针将不胜感激!

编辑:使用工具查看分配后,我注意到它们指向下面屏幕截图中显示的 te 线:

 NSData *responseData =  [NSURLConnection sendSynchronousRequest:req returningResponse:&urlResponse error:&error];

我还在@autoreleasepool 中附上了我的代码,请帮忙,因为我仍然不知道如何避免这种情况。

内存泄漏

4

1 回答 1

0

当您将这些指针设置为 nil 时,对象仍在内存中:

responseData=nil;
strResponse=nil;
strZipEncoded=nil;

试试这个,寻找其他没有释放内存的地方:

  [responseData release];
  [strResponse release];
  [strZipEncoded release];
于 2013-09-17T12:58:59.850 回答