Lua - Какао - Строка Concat - Простая таблица для NSArray - PullRequest
0 голосов
/ 07 сентября 2010

Совместимость с Mac OS X 10.5, требуется совместимость с Lua 5.0 (следовательно, нельзя использовать текущую партию мостов LuaObjc.)

Мой скрипт lua создает индексированную таблицу, содержащую десятки тысяч строк.

Основная проблема: как быстро объединить эти строки с разделителем новой строки в одну строку?

Приготовление мази: даже при использовании дружественного к контуру кода для сбора мусора (предоставляется в стеке потока) результаты для этой цели слишком длинны.(10 секунд против 1 минуты для решения грубой силы.)

Предлагаемое решение: переложить задание в Какао, где это можно сделать за доли секунды, используя NSArray -componentsJoinedByStringmethod.

Новая ложка дегтя: как получить данные таблицы из Lua в Cocoa?

Скрипт вызывает зарегистрированную функцию C, передавая ей таблицу.Функция C пытается получить таблицу в стеке:

// Get an NSArray of strings from the first argument on the stack (a table).
NSArray *strings = nsArrayFromIndexedTable(luaState, index_1Based);

...

// Given a simple table consisting of numbers or strings, returns an NSArray.
// Nested subtables are not followed.

NSArray * nsArrayFromIndexedTable(lua_State *L, int argIdx)
{
    // (Allegedly) stops GC.
    lua_setgcthreshold(L, INT_MAX);

    // Arg must be a table.
    luaL_checktype(L, argIdx, LUA_TTABLE);

    // Get num elements in table, build an array with that many.
    int count = luaL_getn(L, 1);

    NSMutableArray *array = [NSMutableArray arrayWithCapacity: count];

    int i;
    for (i = 1; i <= count; i++) {

        lua_rawgeti(L, argIdx, i);
        int valueType = lua_type(L, -1);
        id value = 0x00;

        if (valueType is_eq LUA_TNUMBER) {
            value = [NSNumber numberWithDouble:lua_tonumber(L, -1)];
        } else if (valueType is_eq LUA_TSTRING) {
            value = [NSString stringWithUTF8String:lua_tostring(L,  -1)];
        }

        if (value) {
            [array addObject:value];
        }
    }

    // Resume GC
    lua_setgcthreshold(L, 0);    // INTERMITTENT EXC_BAD_ACCESS CRASH HERE!!!!

    return array;
}

Проблема: вызов этой функции с (очень большой) таблицей строк Lua (с перерывами) приводит к EXC_BAD_ACCESS.

Результаты отладчика носят эпизодический характер;иногда не предоставляя ничего полезного, но я смог выяснить, что:

  • Если эти строки включены в Lua GC, сбой происходит в lua_setgcthreshold, ближе к концу функции.

  • Но ... если эти строки Lua GC закомментированы, происходит сбой в [array addObject: value]

(NSZombieEnabled включено,но не предоставляет полезной информации.)

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2010

Возможно, вы слишком много наращиваете свой стек C. Я не знаком с Какао, но думаю, что значения Lua не обязательно должны быть доступны постоянно - строка должна быть скопирована в NSString. Если это так, попробуйте добавить lua_pop(L, 1) в конце цикла, чтобы очистить стек C и не дать ему расти.

0 голосов
/ 07 сентября 2010

Это:

int count = luaL_getn(L, 1);

Должно быть:

int count = luaL_getn(L, argIdx);    

Таким образом, возможно, вы получаете неправильный счетчик строк и сканируете конец таблицы.

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