1

我有一个 SKShapeNode,我将形状设置为 RoundedRectangle,但是当我分析代码时,我收到一条警告,指出对象可能存在泄漏。

我的界面文件如下:

#import <SpriteKit/SpriteKit.h>

@interface letterSpace : SKShapeNode

-(instancetype) initWithCharacter:(NSString *)character xPosition:(float)x yPosition:(float)y device:(NSString *)device;
    @property(nonatomic, assign) BOOL occupied;
    @property(nonatomic, assign) BOOL whiteSpace;
    @property(nonatomic, retain) NSString *character;
    @property (atomic) float secondLineX;
    @property (atomic) float secondLineY;


@end

然后实现是

 #import "letterSpace.h"

@implementation letterSpace
-(instancetype) initWithCharacter:(NSString *)character xPosition:(float)x yPosition:(float)y device:(NSString *)device{
    self = [super init];
        if(self){

            if ([device isEqualToString:@"IPHONE"]) {
                [self setPath:CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 2), 1, 1, nil)]; // Potential Leak of an object on this line
                _secondLineX = 36*8;
                _secondLineY = -36;
            }else{
                [self setPath:CGPathCreateWithRoundedRect(CGRectMake(0, 0, 60, 3.5), 1, 1, nil)]; // Potential Leak of an object on this line
                _secondLineX = 575;
                _secondLineY = -71;
            }
            self.strokeColor = [UIColor clearColor];
            if ([character  isEqual: @" "]) {
               self.occupied = TRUE;
               self.fillColor = [UIColor clearColor];
               self.character = character;
               self.whiteSpace = TRUE;
            }else{
                self.whiteSpace = FALSE;
                self.occupied = FALSE;
                self.fillColor = [UIColor colorWithRed:80.0f/255.0f
                                                green:227.0f/255.0f
                                                                 blue:194.0f/255.0f
                                                                alpha:1];
            }
            if (y <8) {
                self.position = CGPointMake(x, 0);
            }
            else{
                self.position = CGPointMake(x - _secondLineX, _secondLineY);
            }


            self.name = character;
        }
        return self;
    }

@end

任何想法如何解决这个泄漏?或者是什么原因造成的?

4

1 回答 1

1

当您使用 Core Foundation 对象时,如果您调用以下函数*,您将拥有一个对象:

  • 在名称中嵌入“创建”;
  • 在名称中嵌入“副本”;

*然而,这不适用于返回 Objective-C 对象的方法。

如果您是对象的所有者,则必须在使用CFRelease(或相应的特定于类型的变体)完成使用它时放弃所有权。

在 ARC 环境中,编译器不会自动管理 Core Foundation 对象的生命周期。您必须调用CFRetainCFRelease(或相应的特定于类型的变体)

如果你在 Objective-C 和 Core Foundation 对象之间进行转换,你还需要告诉编译器对象的所有权:

  • __bridge在没有所有权转移的情况下在 Objective-C 和 Core Foundation 之间转移一个指针;
  • __bridge_retainedCFBridgingRetain将 Objective-C 指针转换为 Core Foundation 指针,并将所有权转移给您。您负责调用CFRelease或相关函数以放弃对象的所有权;
  • __bridge_transferCFBridgingRelease将非 Objective-C 指针移动到 Objective-C 并将所有权转移给 ARC。ARC 负责放弃对象的所有权。

所以,在你的情况下:

path有一种类型CGPathRef,它来自采用核心基础内存管理约定的核心图形框架。因此,我们应用规则“如果您调用名称中嵌入了“创建”的方法 - 您拥有它”。无论是手动(必须手动)还是自动(ARC 环境不会自动管理核心基础对象的生命周期)内存管理都必须释放此对象。

CGPathRef path = CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 2), 1, 1, nil);
[self setPath:path];
CGPathRelease(path);

或者你可以使用可可类似物bezierPathWithRoundedRect:(NSRect)rect xRadius:(CGFloat)xRadius yRadius:(CGFloat)yRadius

另外,我建议您使用NULL而不是nilin CGPathCreateWithRoundedRect

于 2016-04-01T09:19:03.643 回答