How to properly keep a local reference to a child CCNode in a custom class in ARC

心不动则不痛 提交于 2019-12-13 07:35:21

问题


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?

来源:https://stackoverflow.com/questions/26665092/how-to-properly-keep-a-local-reference-to-a-child-ccnode-in-a-custom-class-in-ar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!