0

So, I want to hold a local reference to a child CCNode in a CCNode custom class without creating a retain cycle or without having the compiler complaining that the property or instance variable may be unpredictable set to nil

For instance with this custom class

@interface MyNode : CCNode
@property (nonatomic, strong) CCNode *background;
+ (id)nodeWithBackground:(id)background;
@end

@implementation MyNode

+ (id)nodeWithBackground:(id)background {
    MyNode *node = [MyNode node];
    node.background = background;
    node.background.scale = 0.01;//(*)
    return node;
}

- (void)setBackground:(CCNode *)background {
    if (_background) {//(*)
        [self removeChild:_background];
    }
    if (background) {
        [self addChild:background];
    }
    _background = background;
}

@end

...I have a retain cycle creating a node like this

CCSprite *background = [CCSprite ...];
MyNode *node = [MyNode nodeWithBackground:background];
[self addChild:node];

where background and node are never freed from memory when the scene is replaced

Changing the property background to weak causes the compiler to complain in the lines with star (*) in the code above saying that the weak property or instance variable may be unpredictable set to nil

Update:

This is another approach with a weak instance variable and the settler and getter methods, the local strong variable (*) is because if the method uses the weak ivar _background the compiler complains saying that it may be unpredictable set to nil.

@interface MyNode : CCNode {
    __weak CCNode *_background;
}
+ (id)nodeWithBackground:(id)background;
- (void)setBackground:(CCNode *)background;
- (CCNode *)background;
@end

@implementation MyNode

+ (id)nodeWithBackground:(id)background {
    MyNode *node = [MyNode node];
    node.background = background;
    node.background.scale = 0.01;
    return node;
}

- (void)setBackground:(CCNode *)background {
    __strong CCNode *localRef = _background; //(*)
    if (localRef) {
        [self removeChild:localRef];
    }
    if (background) {
        [self addChild:background];
    }
    _background = background;
}

- (CCNode *)background {
    return _background;
}
@end

Is this approach a good thing to do in this case?

4

0 回答 0