0

ARC에 문제가 있습니다. 내가하는 일은 동기화입니다. 웹 서비스에서 데이터를 요청하고이를 데이터베이스 (fmdb)로 작성합니다.블록을 사용할 때 ARC가 메모리를 비우지 않습니다.

는 여기에 내가 웹 서비스에서 얻는 데이터는 75메가바이트에 대한 내 전체 코드

dispatch_async(queue, ^{ 

    hud.labelText = [NSString stringWithFormat:@"Sincronizzo le aziende"]; 
    [Model syncAziende:^(id response, NSError *error) { 
     hud.progress += offset; 
     dispatch_semaphore_signal(sema); 
    }]; 
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 

    hud.labelText = [NSString stringWithFormat:@"Sincronizzo i contatti"]; 
    [Model syncContatti:^(id response, NSError *error) { 
     hud.progress += offset; 
     dispatch_semaphore_signal(sema); 
    }]; 
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 

      .... 

+ (void)syncAziende:(RequestFinishBlock)completation 
{ 
    [self syncData:^(id response, NSError *error) { 
     completation(response,error); 
    } wsEndPoint:kCDCEndPointGetAziende tableName:kCDCDBAziendeTableName]; 
} 

+ (void)syncData:(RequestFinishBlock)completation wsEndPoint:(NSString*) url tableName:(NSString *)table 
{ 
    NSLog(@"%@",url); 
    [self getDataFromWS:^(id WSresponse, NSError* WSError) 
    { 
     if (!WSError) 
      [self writeDatatoDB:^(id DBresponse,NSError* DBError) 
       { 
        completation(DBresponse,DBError); 
       }table:table shouldDeleteTableBeforeUpdate:YES data:WSresponse]; 
     else 
      completation(nil,WSError); 
     WSresponse = nil; 
    }WSUrl:url]; 
} 

+ (void)getDataFromWS:(RequestFinishBlock)completation WSUrl:(NSString *)svcUrl 
{ 
    [self getJsonDataFromURL:^(id response, NSError *error) 
    { 
     completation(response,error); 
    }url:svcUrl]; 
} 

+(void)getJsonDataFromURL:(RequestFinishBlock)completation url:(NSString*)url 
{ 
    AFHTTPRequestOperationManager *manager = [self getAuthorizedRequestionOperationManager]; 

    if (manager) { //OK I'have internet connection 
     [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
     [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
     [manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"]; 

     [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
      completation([responseObject objectForKey:@"d"],nil); 
     } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
      completation(nil,error); 
     }]; 
    } 
    else //ERROR: I don't have internet connection 
    { 
     NSDictionary *dError = [[NSDictionary alloc] initWithObjectsAndKeys:kCDCErrorNoInternetConnectionStatusMessage,@"error", nil]; 
     NSError *error = [[NSError alloc]initWithDomain:url code:kCDCErrorNoInternetConnectionStatusCode userInfo:dError]; 
     completation(nil,error); 
    } 
} 


+ (void) writeDatatoDB:(RequestFinishBlock)completion 
       table:(NSString *)tableName 
shouldDeleteTableBeforeUpdate:(BOOL)deleteTable 
        data:(NSMutableArray *)data 
{ 
    NSLog(@"Inizio le operazioni sul database"); 
    __block int errors = 0; 

    classAppDelegate *appDelegate = (classAppDelegate *)[[UIApplication sharedApplication]delegate]; 
    FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:appDelegate.dbFilePath]; 
    [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { 

     if (deleteTable) 
      [db executeUpdate:[NSString stringWithFormat:@"DELETE FROM %@", tableName]]; 

     for (NSDictionary *jString in data) 
     { 
      NSMutableArray* cols = [[NSMutableArray alloc] init]; 
      NSMutableArray* vals = [[NSMutableArray alloc] init]; 

      for (id currentValue in jString) 
      { 
       if (![currentValue isEqualToString:@"__metadata"]) { 
        [cols addObject:currentValue]; 
        [vals addObject:[jString valueForKey:currentValue]]; 
       } 
      } 

      NSMutableArray* newCols = [[NSMutableArray alloc] init]; 
      NSMutableArray* newVals = [[NSMutableArray alloc] init]; 
      NSString *value = @""; 

      for (int i = 0; i<[cols count]; i++) { 
       @try { 
        NSString *element = [vals objectAtIndex:i]; 
        if (![element isKindOfClass:[NSNull class]]) { 
         value = [element stringByReplacingOccurrencesOfString:@"'" withString:@"''"]; 
         [newCols addObject:[NSString stringWithFormat:@"'%@'", [cols objectAtIndex:i]]]; 
         [newVals addObject:[NSString stringWithFormat:@"'%@'", value]]; 
        } 
       } 
       @catch (NSException *exception) { 

       } 
      } 

      NSString* sql = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (%@)",tableName, [newCols componentsJoinedByString:@", "], [newVals componentsJoinedByString:@", "]]; 
      [db executeUpdate:sql]; 

      if([db lastErrorCode] == 1) //ERRORE!! 
      { 
       errors++; 
      } 
     } 
     completion(nil,nil); 


     NSLog(@"Ho completato le operazioni sul database con %i errori",errors); 
    }]; 
} 

하지만 엑스 코드에서 나는 메모리가 아이 패드 2 충돌하게 500메가바이트로 이동을 참조하십시오.

답변

3

확실히 블록에주기가입니다.

주로 블록에서 자기를 호출 할 때 발생합니다. 그래서 자기는 블록과 메인 시퀀스에 유지됩니다. 그래서 둘 다 서로 붙잡고 있으며 ARC는 양쪽 모두가 다른 쪽에서 필요하다고 생각합니다.

약한 자기 또는 이와 유사한 방법을 사용해야합니다. 여기에 도움이

: The Correct Way to Avoid Capturing Self in Blocks With ARC

+0

감사를 참조하지만 난 어떤 곳에서 자기를 사용하지 마십시오. – user3463206

+0

iVar (예 : _myLabel)를 사용하면 끝납니다. – AncAinu

+0

모델에 정적 메서드 사용 코드가 있으면 로컬 인스턴스 유형이 없습니다. – user3463206