代码之家  ›  专栏  ›  技术社区  ›  Johnny Rockex

内存泄漏,但cContextRelease会破坏视图

  •  0
  • Johnny Rockex  · 技术社区  · 7 年前

    我面临一个记忆问题:

    使用一个自定义的background.m类,我将根据传递给类的颜色选择创建渐变背景。问题出现在,似乎有泄漏,没有什么令人兴奋的,但随着时间的推移积累。释放drawrect中的上下文会消除内存问题,但不会绘制渐变。最佳解决方案/解决方案是什么?使用苹果的渐变?下面是传递给background类的drawrect方法的代码:

        //1. create vars
        float increment = 1.0f / (colours.count-1);
        CGFloat * locations = (CGFloat *)malloc((int)colours.count*sizeof(CGFloat));
        CFMutableArrayRef mref = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    
        //2. go through the colours, creating cgColors and locations
        for (int n = 0; n < colours.count; n++){
            CFArrayAppendValue(mref, (id)[colours[n] CGColor]);
            locations[n]=(n*increment);
        }
    
        //3. create gradient
        CGContextRef ref = UIGraphicsGetCurrentContext();
        CGColorSpaceRef spaceRef = CGColorSpaceCreateDeviceRGB();
        CGGradientRef gradientRef = CGGradientCreateWithColors(spaceRef, mref, locations);
    
        if (isHorizontal){
            CGContextDrawLinearGradient(ref, gradientRef, CGPointMake(0.0, 0.0), CGPointMake(self.frame.size.width, 0.0), kCGGradientDrawsAfterEndLocation);
        } else if (isDiagonal) {
            CGContextDrawLinearGradient(ref, gradientRef, CGPointMake(0.0, 0.0), CGPointMake(self.frame.size.width, self.frame.size.height), kCGGradientDrawsAfterEndLocation);
        } else {
            CGContextDrawLinearGradient(ref, gradientRef, CGPointMake(0.0, 0.0), CGPointMake(0.0, self.frame.size.height), kCGGradientDrawsAfterEndLocation);
        }
    
        CGContextRelease(ref); //ISSUE
        CGColorSpaceRelease(spaceRef);
        CGGradientRelease(gradientRef);
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Rob Napier    7 年前

    每个 Create , Copy Retain 必须通过一个 Release . 你在这里两次违反了。

    首先,你没有平衡 释放 对于 CFArrayCreateMutable .

    第二,你在释放一些你不拥有的东西( ref )

    相关的,每一个 malloc 必须通过 free ,所以你漏了 locations .

    清理代码应该是

    free(locations);
    CGRelease(mref);
    CGColorSpaceRelease(spaceRef);
    CGGradientRelease(gradientRef);