2015-04-18 108 views
-6

我正在开发一个Gps地图概念在我的app.Here我发现内存泄漏在我的代码我解决了一些内存泄漏终于在这里三个内存泄漏即将到来我不知道如何解决这个请指导我任何人。这是我的代码库和屏幕快照如何在objective-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

是iam使用ARC @MidhunMP –

+0

您是否分析了您的应用程序的分配和内存泄漏?你能否提供任何额外的信息来表明哪里出现内存泄漏? –

回答

2

对于屏幕截图#2,它看起来像你不释放CGImageRef对象。为此,要清理它,您应该使用:

CGImageRelease(image); 

...当您完成使用CGImageRef时。

有关此问题的更多信息(以及它与CFRelease的区别)可以在此问题处找到:Releasing CGImage (CGImageRef)请注意,即使您使用ARC,在使用任何基于C的API时也需要特别小心,特别是如果你将它们与一些Obj-C对象混合在一起。

对于第一个截图和你发布的代码很难说,因为逻辑非常复杂,但是我建议如果你使用的是ARC,那么我会问如果在所有的初始化器上使用'autorelease'是非常必要的。当我尝试在ARC项目中使用'autorelease'时,它甚至不会让我:Xcode给出消息“ARC禁止'autorelease'的显式消息发送。”您可能想要确认您是否确实为此项目启用了ARC。

如果它是有帮助的,这个问题讨论开启ARC为您的项目:How to enable/disable ARC in an xcode project?


编辑新增截图

在Xcode的这张截图的错误信息很清楚地表明问题出在哪里。当调用'CGColorSpaceCreateDeviceRGB'时,这会创建一个你明确负责释放的对象。

如果选中的文件上CGColorSpaceCreateDeviceRGB你会看到,这也是在文档“返回”的说明中指出:

CGColorSpaceCreateDeviceRGB() Returns Description

所以你要叫“CGColorSpaceCreateDeviceRGB”你以前创建CGContextRef,你需要在使用CGColorSpaceRelease完成上下文之后释放它:

CGColorSpaceRef myColorSpaceRef = CGColorSpaceCreateDeviceRGB(); 

CGContextRef myContext = CGBitmapContextCreate(...); 

... 

CGContextRelease(myContext); 

CGColorSpaceRelease(myColorSpaceRef); 
+0

第一屏拍摄解决方案? –

+0

我建议您确认您已将ARC适当添加到项目中 - 先将项目转换为ARC项目,然后再执行下一步(请注意,这不是从Build Phases >> Compile Sources完成的)。 –

+0

是的,我同意,如果这些autorelease消息没有产生警告,那么ARC可能没有打开,至少对于这个类,如果不是整个目标。如果你认为ARC是开启的而且不是的话,那么我希望你的代码确实会非常泄漏。 – Jef

1

如果使用ARC,你不需要管理内存。

如果您没有,请使用[object release]

强烈建议您在继续阅读之前阅读Managing Memory in Objective-C

+0

我是阿尔雷迪添加ARC。在这里我不知道如何释放该对象。 –

+0

@Ram然后你不需要发布任何东西。 –

+0

即使使用ARC,我也已经在BuildPhases - > CompileSourses –