2015-04-18 2 views
-6

Я разрабатываю концепцию карты Gps в своем приложении. Здесь я обнаруживаю утечки памяти в своем коде. Я разрешаю утечку памяти. Наконец, здесь происходит утечка памяти. Я не знаю, как это решить. Пожалуйста, назовите меня всем. Это мой код базы и снимки экранаКак освободить память в объективе-c?

https://drive.google.com/file/d/0B14zCKcRh39AWm1QNTFMejNqOGc/view?usp=sharing

https://drive.google.com/file/d/0B14zCKcRh39AcmhyM3R3c1ZrZE0/view?usp=sharing

-(NSArray *)decodePolyLine: (NSMutableString *)encoded { 
     [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\" 
            options:NSLiteralSearch 
             range:NSMakeRange(0, [encoded length])]; 
     NSInteger len = [encoded length]; 
     NSInteger index = 0; 
     NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease]; 
     NSInteger lat=0; 
     NSInteger lng=0; 
     while (index < len) { 
      NSInteger b; 
      NSInteger shift = 0; 
      NSInteger result = 0; 
      do { 
       b = [encoded characterAtIndex:index++] - 63; 
       result |= (b & 0x1f) << shift; 
       shift += 5; 
      } while (b >= 0x20); 
      NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1)); 
      lat += dlat; 
      shift = 0; 
      result = 0; 
      do { 
       b = [encoded characterAtIndex:index++] - 63; 
       result |= (b & 0x1f) << shift; 
       shift += 5; 
      } while (b >= 0x20); 
      NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1)); 
      lng += dlng; 
      NSNumber *latitude = [[[NSNumber alloc] initWithFloat:lat * 1e-5] autorelease]; 
      NSNumber *longitude = [[[NSNumber alloc] initWithFloat:lng * 1e-5] autorelease]; 
      printf("[%f,", [latitude doubleValue]); 
      printf("%f]", [longitude doubleValue]); 
      CLLocation *loc = [[[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]] autorelease]; 
      [array addObject:loc]; 
     } 

     return array; 
    } 

    -(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t { 
     NSString* saddr = [NSString stringWithFormat:@"%f,%f", f.latitude, f.longitude]; 
     NSString* daddr = [NSString stringWithFormat:@"%f,%f", t.latitude, t.longitude]; 

     NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.google.com/maps?output=dragdir&saddr=%@&daddr=%@", saddr, daddr]; 
     NSURL* apiUrl = [NSURL URLWithString:apiUrlStr]; 
     NSLog(@"api url: %@", apiUrl); 
     NSError *error; 
     NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:&error]; 
     NSString* encodedPoints = [apiResponse stringByMatching:@"points:\\\"([^\\\"]*)\\\"" capture:1L] ; 

     return [self decodePolyLine:[encodedPoints mutableCopy]]; 


} 




-(void) updateRouteView { 
    CGContextRef context = CGBitmapContextCreate(nil, 
                routeView.frame.size.width, 
                routeView.frame.size.height, 
                8, 
                4 * routeView.frame.size.width, 
                CGColorSpaceCreateDeviceRGB(), 
                (kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast) | (kCGBitmapByteOrderMask & kCGBitmapByteOrderDefault)) ; 


    CGContextSetStrokeColorWithColor(context, lineColor.CGColor); 
    CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0); 
    CGContextSetLineWidth(context, 3.0); 

    for(int i = 0; i < routes.count; i++) { 
     CLLocation* location = [routes objectAtIndex:i]; 
     CGPoint point = [mapView convertCoordinate:location.coordinate toPointToView:routeView]; 

     if(i == 0) { 
      CGContextMoveToPoint(context, point.x, routeView.frame.size.height - point.y); 
     } else { 
      CGContextAddLineToPoint(context, point.x, routeView.frame.size.height - point.y); 
     } 
    } 

    CGContextStrokePath(context); 

    CGImageRef image = CGBitmapContextCreateImage(context); 
    UIImage* img = [UIImage imageWithCGImage:image]; 
    CGContextRelease(context); 
    routeView.image = img; 
    // CGContextRelease(context); 



} 
+0

Вы используете ARC? –

+0

Да, я использую ARC @MidhunMP –

+0

Профилировали ли вы свое приложение для распределения и утечки памяти? Можете ли вы предоставить дополнительную информацию из профилирования, указывающую, где появляется утечка памяти? –

ответ

2

Для скриншота # 2 похоже, что вы не выпускаете объект CGImageRef. Для этого, чтобы очистить это, вы должны использовать:

CGImageRelease(image); 

... когда вы закончите использовать CGImageRef.

Подробнее об этом (и о том, как он отличается от CFRelease) можно найти по этому вопросу: Releasing CGImage (CGImageRef) Имейте в виду, что даже если вы используете ARC, вам нужно быть осторожным при использовании любого из API на основе C, особенно если вы смешиваете их вместе с некоторыми объектами Obj-C.

Для первого снимка экрана и кода, который вы отправили, сложно сказать, так как логика довольно сложная, однако я бы посоветовал, если вы используете ARC, тогда я бы поставил вопрос, используете ли вы «autorelease» на всех своих инициализаторах действительно необходимо. Когда я пытаюсь использовать «autorelease» в проекте ARC, это даже не позволяет мне: Xcode дает сообщение «ARC запрещает явное сообщение отправки« autorelease »». Вы можете подтвердить, что у вас действительно есть ARC для этого проекта.

В случае полезно, этот вопрос обсуждается включение ARC для вашего проекта: How to enable/disable ARC in an xcode project?


EDIT для добавляемого скриншоте

Сообщение об ошибке из Xcode для этого экрана довольно четко указывает где проблема здесь. При вызове 'CGColorSpaceCreateDeviceRGB' это создает объект, за который вы отвечаете за освобождение явно.

Если вы обратитесь к документации по CGColorSpaceCreateDeviceRGB вы увидите, что это также указано в описании ДОКУМЕНТАЦИЯ «возвращает»:

CGColorSpaceCreateDeviceRGB() Returns Description

Поэтому вы хотите назвать «CGColorSpaceCreateDeviceRGB», прежде чем создавать CGContextRef, и вам нужно будет освободить его после завершения контекста с использованием CGColorSpaceRelease как такового:

CGColorSpaceRef myColorSpaceRef = CGColorSpaceCreateDeviceRGB(); 

CGContextRef myContext = CGBitmapContextCreate(...); 

... 

CGContextRelease(myContext); 

CGColorSpaceRelease(myColorSpaceRef); 
+0

Первое решение для снятия экрана? –

+0

Я рекомендую вам подтвердить, что вы добавили ARC надлежащим образом в свой проект - сначала конвертируйте проект в проект ARC, а затем выполните следующие шаги (обратите внимание, что это не делается из «Фазы сборки» >> «Скомпилировать источники»). –

+0

Да, я согласен, что если эти сообщения автоопределения не генерируют предупреждение, ARC, вероятно, не включается, по крайней мере, для этого класса, если не цели. И если вы считаете, что ARC включен, и это не так, я ожидаю, что ваш код будет очень неприятным. – Jef

1

Если вы используете ARC, вам не нужно управлять памятью.

Если вы этого не сделаете, просто используйте [object release].

Настоятельно предлагаю вам прочитать Managing Memory in Objective-C, прежде чем идти дальше.

+0

Я добавил alredy ARC. Вот я не знаю, как выпустить этот объект. –

+0

@Ram Тогда вам не нужно ничего отпускать. –

+0

Я уже добавил ARC в BuildPhases -> CompileSourses –

Смежные вопросы