gpt4 book ai didi

ios - 属性和 ARC

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:17:36 26 4
gpt4 key购买 nike

我正在使用 ARC 和 Cocos2d 2.0 作为静态库(它不使用 ARC 并且被编译为一个单独的目标)。我翻译了一个旧项目(没有 ARC 制作),我想知道以这种方式声明属性是否有一些潜在的保留周期问题:

@interface PlayerData : NSObject <NSCoding> {
}


//Is ok to save this as if the game gets paused you may want to save this.
@property (readwrite, nonatomic) int numberOfHits;
@property (readwrite, nonatomic) bool everBeenHitInCurrentLevel;
@property (readwrite, nonatomic) int hitsForOneHearth;

我注意到我的各种场景会随着时间的推移而积累内存。此外,我在 CCLayer 方法 (MyScene : CCLayer) 的释放方法中添加了一个 CCLOG 调用,但它永远不会被调用。这就是我创建场景的方式(我使用“[CCDirector sharedDirector] replaceScene”方法替换它

+ (id) sceneWithLevelName:(LevelName)name
{
CCScene *scene = [CCScene node];
ShooterScene * shooterLayer = [[self alloc] initWithId:name];
[scene addChild:shooterLayer];


return scene;
}

编辑:当我意识到我愚蠢地没有包含对象的示例并且仅使用原始数据类型时,我将在此处粘贴场景中的一些元素片段:CharacterSelection、ShooterScene 和 PlanetSelectionMenu:

//ShooterScene
@interface ShooterScene : CCLayer {
HudLayer * hudLayer;
....
}

@property(readwrite, nonatomic) CCSpriteBatchNode* backgroundAndEnemiesBatchNode;
@property(readwrite, nonatomic) ShipEntity* playerShip;
... etc..


Please note that I do not declare member variables for properties like playerShip and backgroundAndEnemiesBatchNode beause, as far as I can understand, should suffice the property declaration (but please correct me if I am wrong or if the approach may cause issues).

//CharacterSelectionScene
@interface CharacterSelectionScene : CCLayer {
int currentlySelectedCharacterSpriteTag;
CCSprite * lights;
CCLayer * spritesLayer;
...
}

//PlanetSelectionMenu
#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface PlanetSelectionMenu : CCLayer {
CCLayer * backgroundLayer; // Added background images here
CCLayer * alwaysPresentItems;
}

+ (id) scene;

@end

请注意,每次我从 PlanetSelectionMenu 转到 CharacterSelectionScene - 反之亦然 - 内存都会增加。然而,在这种情况下,我没有使用任何属性,而是“只是”将对象 (CCSprites) 添加到图层和批处理节点。

编辑 2:这是我在通过 Menu->CharacterSelection->PlanetSelectionScene 等运行时在 Allocation 中看到的内容。似乎平均 LiveBytes 为 4MB,而且,因为我当时只看到一个场景,所以我假设没有保留周期。那为什么我会收到那些讨厌的低内存消息?

enter image description here

最佳答案

虽然默认属性属性现在是 strong,但不会是那些导致保留周期的属性,因为它们是原始类型,默认为 assign

其他三种引入保留循环的常见方法跳入脑海:

  • 您是否在任何地方(@protocol)实现委托(delegate)模式。您的代理人是否总是在必要时引用弱引用?
    -(id) initWithDelegate:(id) target    {        ...        _target = target;   //_target should be a weak reference        ...    }
  • 您的任何子节点是否引用了它们的父节点?
    -(id) initWithParent:(CCNode*) parentNode    {        ...        _parent = parentNode; //_parent should be a weak reference.        ...    }
  • 是否有任何 block 引用self
   ^{[self callSomeMethod];}

应该使用对 self 的弱引用:

   __weak typeof(self) selfReference = self;   ^{[selfReference callSomeMethod];}

我通常发现使用 ARC 查找泄漏的最佳方法不是使用泄漏工具,而是使用分配工具。由于我所有的场景都倾向于在其符号中包含“场景”一词,因此我按场景一词进行过滤。

由于您使用的是 replaceScene,因此一次应该只有一个场景处于事件状态(过渡期间除外),因此您应该只能在对象摘要中看到一个对象。

enter image description here

如果您确实有一个悬而未决的场景,我通常发现最好查看对象是否保留了历史记录。从这里开始,我将每个保留与相应的释放配对,直到找到保留和不释放我的场景的罪魁祸首。更常见的情况是,它不是明显的带有 block 的保留循环,或者声明为强而不是弱的属性。

enter image description here

关于ios - 属性和 ARC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18615475/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com