0

ARC遇到問題。 我所做的是同步:我從web服務請求數據,並將其寫入數據庫(使用fmdb)。ARC在使用塊時不會釋放內存

這裏是我完整的代碼

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); 
    }]; 
} 

我從Web服務得到的數據是約75MB,但在Xcode我看到了那張內存爲500MB,這使得一臺iPad 2的碰撞。

回答

3

您當然在您的區塊中保留了一個保留週期

這種情況主要發生在您呼叫自我時。所以自我保留在方塊和主序列中。所以兩者都互相支持,ARC認爲兩者都是另一方需要的。

你應該使用弱自我或其他方法。

這裏一些幫助:The Correct Way to Avoid Capturing Self in Blocks With ARC

+0

感謝您的答覆,但我沒有在任何地方使用的自我。 – user3463206

+0

如果您使用iVar(例如_myLabel),則它結束。 – AncAinu

+0

如果您看到代碼Model使用靜態方法,則不存在任何類型的本地實例。 – user3463206