NSMapTable WeakMemory在Swift2.0中不起作用?

时间:2015-10-21 08:56:26

标签: swift

当我尝试在swift 2.0中使用NSMapTable时,似乎弱内存选项不起作用。这是我的测试代码:

class TestClass {
    var a: String
    required init(a: String) {
        self.a = a
    }
}

var table = NSMapTable.strongToWeakObjectsMapTable()

var test: TestClass? = TestClass(a:"name")

table.setObject(test, forKey: "a")

if let object = table.objectForKey("a") {
    print(object)
} else {
    print("nil")
}

test = nil

if let test = test {
    print("test")
} else {
    print("nil")
}

if let object = table.objectForKey("a"), let aa = object as? TestClass {
    print(object)
    print(aa.a)
} else {
    print("nil")
}

在我将test设置为nil(“test = nil”)之后,对于键“a”,表格不返回nil。 控制台输出如下:

TestClass
nil
TestClass
name

我也尝试过使用Objective-C的NSMapTable,它运行正常。

我错过了什么吗?或者它是swift2.0中的NSMapTable的错误?

3 个答案:

答案 0 :(得分:1)

<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="0%p" android:toYDelta="0" android:duration="500"/> </set> 如果存在弱弱,弱强或强弱的绑定,有时不释放键和对象。

如果您看到NSMapTable,您可以发现Apple已提及:条目不一定会在填充弱密钥时立即清除

那就是说,如果你尝试下面的,它应该立即释放参考。

NSMapTable.h

答案 1 :(得分:1)

以上是上述代码的Objectic-C版本。

    class Player
    {
        public Texture2D PlayerTexture; //Animation representing the layer
        public Texture2D moveLeft;
        public Texture2D moveRight;
        public Vector2 Position;    //Position of the Player relative to the upper left side of the screen
        public bool Active; //State of the player
        public int Health;  //Amount of hit points the player has
        public int Width { get { return PlayerTexture.Width; } }    //Get width of the player ship
        public int Height { get { return PlayerTexture.Height; } }  //Get height of the player ship

        //Keyboard states used to determine key presses
        KeyboardState currentKeyboardState;
        KeyboardState previousKeyboardState;

        //Mouse states used to track Mouse button press
        MouseState currentMouseState;
        MouseState previousMouseState;

        float playerMoveSpeed;

        //Player moving left or right
        bool movingLeft;
        bool movingRight;

        public void Initialize(Texture2D texture, Vector2 position)
        {
            PlayerTexture = texture;
            Position = position;    //Set the starting position of the player around the middle of the screen and to the back
            Active = true;  //Set the player to be active
            Health = 100;   //Set the player health

            //Set a constant player move speed
            playerMoveSpeed = 8.0f;
        }

        public void PmovingLeft(Texture2D pmoveleft, Vector2 position)
        {
            moveLeft = pmoveleft;
            Position = position;
        }

        public void PmovingRight(Texture2D pmoveright, Vector2 position)
        {
            moveRight = pmoveright;
            Position = position;
        }

        public void Update()
        {
            //Save the previous state of the keyboard so we can determine single key presses
            previousKeyboardState = currentKeyboardState;

            //Read the current state of the keyboard and store it
            currentKeyboardState = Keyboard.GetState();
        }

        public void UpdatePlayer(GameTime gameTime)
        {
            //Keyboard controls

            if (currentKeyboardState.IsKeyDown(Keys.Left))
            {
                Position.X -= playerMoveSpeed;
                movingLeft = true;
            }
            else { movingLeft = false; }
            if (currentKeyboardState.IsKeyDown(Keys.Right))
            {
                Position.X += playerMoveSpeed;
                movingRight = true;
            }
            else { movingRight = false; }
            if (currentKeyboardState.IsKeyDown(Keys.Up))
            {
                Position.Y -= playerMoveSpeed;
            }
            if (currentKeyboardState.IsKeyDown(Keys.Down))
            {
                Position.Y += playerMoveSpeed;
            }

            //Make sure that the player does not go out of bounds
            Position.X = MathHelper.Clamp(Position.X, 0, Game1.screenWidth - Width);
            Position.Y = MathHelper.Clamp(Position.Y, 0, Game1.screenHeight - Height);
        }

        public void Draw(SpriteBatch spriteBatch)
        {


            if (movingLeft)
            {
                spriteBatch.Draw(moveLeft, Position, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
            }
            else { spriteBatch.Draw(PlayerTexture, Position, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); }
            if (movingRight)
            {
                spriteBatch.Draw(moveRight, Position, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
            }
            else { spriteBatch.Draw(PlayerTexture, Position, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); }
            }         
        }

这段代码工作正常,只返回我想要的东西。当我将testObject设置为nil时。 mapTable立即变空。输出如下:

NSMapTable *mapTable = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:10];

TestClass *testObject = [[TestClass alloc] initWithName:@"a"];

[mapTable setObject:testObject forKey:@"a"];

NSLog(@"%@", mapTable);
testObject = nil;
NSLog(@"%@", mapTable);

我的问题:为什么NSMapTable在Swift中表现不同?

答案 2 :(得分:1)

“NSMapTable专注于强引用和弱引用意味着Swift的流行值类型只是一种禁止引用类型,请。”

http://nshipster.com/nshashtable-and-nsmaptable/