分配属性,ARC和Core Foundation对象

ver*_*rec 4 objective-c core-foundation automatic-ref-counting

编辑2.

感谢Ken,现在正在努力.我甚至认为我理解为什么:-)

这是修改后的行:

- (void) reCreatePath {
    CGMutablePathRef p = ::CGPathCreateMutable() ;

    ::CGPathMoveToPoint         (p, 0, TL.x, TL.y) ;
    // [snip]
    ::CGPathAddLineToPoint      (p, 0, BL.x, BL.y) ;
    ::CGPathCloseSubpath(p) ;


    self.path = p ;
    ::CGPathRelease(p) ;   // <<== THIS IS IT!! :-)
}
Run Code Online (Sandbox Code Playgroud)

编辑.

我还是不明白.我试过Chuck的建议:

@property (nonatomic, strong) __attribute__((NSObject)) CGPathRef  path ;
Run Code Online (Sandbox Code Playgroud)

像这样:

@interface TopLeftSlidingView  ()

@property (nonatomic, strong) __attribute__((NSObject)) CGPathRef  path ;

@end
Run Code Online (Sandbox Code Playgroud)

在我重新创建CGPath的时候:

- (void) reCreatePath {
    CGMutablePathRef p = ::CGPathCreateMutable() ;

    ::CGPathMoveToPoint         (p, 0, TL.x, TL.y) ;
    // [snip]
    ::CGPathAddLineToPoint      (p, 0, BL.x, BL.y) ;
    ::CGPathCloseSubpath(p) ;


//    self.path = (__bridge CGMutablePathRef) p ;
//    self.path = (__bridge_transfer CGMutablePathRef) p ;
//    self.path = (__bridge_retained CGMutablePathRef) p ;
    self.path = p ;
}
Run Code Online (Sandbox Code Playgroud)

三个注释掉的行中的任何一行都会导致编译器错误.非注释行确实编译,但会生成分析器警告:

/Users/verec/Projects/WordGame/WordGame/classes/TopLeftSlidingView.mm:211:26:
 Call to function 'CGPathCreateMutable' returns a Core Foundation object with
 a +1 retain count
Run Code Online (Sandbox Code Playgroud)

其次是:

/Users/verec/Projects/WordGame/WordGame/classes/TopLeftSlidingView.mm:225:5:
 Object leaked: object allocated and stored into 'p' is not referenced later 
 in this execution path and has a retain count of +1
Run Code Online (Sandbox Code Playgroud)

我就是不明白 :(


考虑:

@interface Test : NSObject

@property (nonatomic, assign) CGColorRef color ;

@end

@implementation Test

- (void) dealloc {
    if (self.color) {
        ::CGColorRelease(self.color) ;
        self.color = 0 ;
    }
}

- (id) init {
    if (self = [super init]) {
        self.color = ::CGColorRetain([UIColor blueColor].CGColor) ;
    }
    return self ;
}

@end
Run Code Online (Sandbox Code Playgroud)

除了分析仪报告警告之外,所有这些都编译(并且看似运行)很好.

从本质上讲,这段代码所说的是:"请ARC,不要费心去做任何事情color,请按照你对待任何其他assign财产的方式对待它,无论是BOOL还是CGFloat,我都在处理内存管理我自己一个人!"

除了ARC拒绝听我并仍然抱怨!

我在这里读了很多关于SO的问题,但似乎没有一个问题可以解决这个问题......

这里的关键是,编译器(虽然不是分析器)似乎同意,是通过声明属性`assign'我声称我自己处理它...

所以我一定是错的,但我不明白为什么......

怎么了?

Chu*_*uck 12

如果您正在使用自动合成的getter和setter,那么确实存在内存管理问题.在setter中,你的CGColor需要被释放并保留新的值,但是assign访问者不会为你做这件事 - 它实际上只是将新指针值赋给变量.您需要实现自己的访问器才能正确管理内存.

但是,如果您愿意,ARC可以为您处理此问题,而不是您自己必须这样做.只是声明它是这样的:

@property(nonatomic, strong) __attribute__((NSObject)) CGColorRef color;
Run Code Online (Sandbox Code Playgroud)

  • 您仍负责正确的本地内存管理.在这种情况下,在分配给属性之后,你必须要`CGPathRelease(p);`.该属性是适当的内存管理,但不会照顾本地. (2认同)