Как я могу связать вызовы функций с промежуточными возвращаемыми объектами в Lua без сборщика мусора, немедленно уничтожающего объекты? - PullRequest
0 голосов
/ 03 февраля 2019

У меня есть строка кода в Lua, такая как:

mv.getLabelChildByNameSequence("confirm_btn|button|no_icon_txt").setVisible(false);

getLabelChildByNameSequence() возвращает объект userdata (созданный c-side), а затем setVisible() вызывает функцию для этого объекта,Проблема в том, что это работает большую часть времени, но иногда сборщик мусора решает уничтожить промежуточный объект сразу после создания и до того, как произойдет вторая часть утверждения.

Я обнаружил, что этоболее успешный:

local no_icon_txt = mv.getLabelChildByNameSequence("confirm_btn|button|no_icon_txt");
no_icon_txt.setVisible(false);

Я подозреваю, что с явной переменной local подсчет ссылок работает, как и ожидалось, и объект не получает мусор, пока локальная переменная не выпадает из области видимости.

Я бы предпочел первый пример второму - он намного компактнее и симпатичнее, и больше похож на то, что вы увидите на таком языке, как c++.Как мне этого добиться?

Кстати, когда происходит сбой, кажется, что он пытается разрешить вызов setVisible() к старому адресу памяти объекта, несмотря на то, что эти данные были собраны только мусором.Любопытно.

РЕДАКТИРОВАТЬ : Хочу отметить, что я использую LunaFive для привязок (http://lua -users.org / wiki / LunaFive ).Нажатие пользовательских данных fn выглядит следующим образом:

    static void push(lua_State * L, T* instance )
    {
        T **a = (T **) lua_newuserdata(L, sizeof(T *)); // Create userdata
        *a = instance;

        luaL_getmetatable(L, T::className);

        lua_setmetatable(L, -2);
    }

, а функция диспетчеризации выглядит следующим образом:

    static int function_dispatch(lua_State * L)
    {
        int i = (int) lua_tonumber(L, lua_upvalueindex(1));
        T** obj = static_cast < T ** >(lua_touserdata(L, lua_upvalueindex(2)));

        return ((*obj)->*(T::methods[i].func)) (L);
    }

getLabelChildByNameSequence() выдвигает новый экземпляр класса Label (давайтескажем), а setVisible() - метод этого класса.

1 Ответ

0 голосов
/ 05 февраля 2019

Исходя из отзывов в комментариях к моему вопросу, я удалил бизнес lua_upvalueindex() в диспетчере функций и вместо этого потребовал, чтобы пользовательские данные были первым аргументом обратного вызова функции.Затем я переключил точечную запись на двоеточие, предоставив неявную self.С тех пор я не смог воспроизвести сбои.

Я до сих пор не понимаю, почему значение upvalue не учитывается правильно до вызова функции.Возможно, при создании объекта чего-то не хватает или что-то в этом роде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...