2014-12-11 12 views
3

루아 5.1에서 테이블에 대해 __gc 메서드를 사용할 수 없다는 문제에 현재 직면하고 있습니다. 루아 5.2에서 구현되었으므로 현재이 문제가 발생합니다. 그러나 루아 표가 수집되면 할당 된 원시 자원을 릴리스하려고합니다. Lua 5.1 용 Lua 5.2에서 __gc metamethod의 기능을 제공하는 해결 방법을 만들 수 있습니까?Lua 5.1 테이블에 대한 __gc 메타 메서드에 대한 해결 방법

+2

테이블에 프록시 개체를 사용하고 '__gc' 메타 메서드를 그 테이블에 넣습니다. 테이블이 수집되면 프록시가 수집되고'__gc' 메소드가 호출됩니다. 이것은 추가 gc주기가 필요할 수 있습니다. –

답변

3

lua 5.1에서 __gc metamethod와 작동하는 유일한 값은 userdata입니다. 당연히 모든 해킹이나 해결 방법은 userdata을 포함해야합니다. 일반적으로 루아 측에서 newuserdata를 생성 할 수있는 방법은 없지만 단지 "hidden"이라는 문서화되지 않은 함수 newproxy이 있습니다.

newproxy은 선택적 bool 또는 userdata 매개 변수를 사용합니다. true을 전달하면 새로운 메타 테이블이 첨부 된 사용자 데이터를 얻게됩니다. 다른 userdata에 전달하면 다음 새 유저 데이터가 전달 된 것과 같은 메타 테이블을 할당 할

를 이제 방금 함께 테이블에 __gc 작업 할 수 있습니다 함수 해킹 할 수 있습니다.

function setmt__gc(t, mt) 
    local prox = newproxy(true) 
    getmetatable(prox).__gc = function() mt.__gc(t) end 
    t[prox] = true 
    return setmetatable(t, mt) 
end 

그리고 빠른 테스트는 동작 확인 : 그

iscollected = false 
function gctest(self) 
    iscollected = true 
    print("cleaning up:", self) 
end 

test = setmt__gc({}, {__gc = gctest}) 
collectgarbage() 
assert(not iscollected) 

test = nil 
collectgarbage() 
assert(iscollected) 

IDEOne Demo

참고 루아 5.2 이상 나중에 테이블에서 __gc이 공식적으로 지원되므로 newproxy이 더 이상 없습니다.

+0

제안 된 솔루션을 사용할 때 우려 할 사항이 하나 있습니다. - 쌍을 기준으로 테이블을 탐색하면() 하나의 추가 키가 생깁니다. 원본 테이블 대신 적절한 메타 메서드를 사용하여 프록시 개체를 사용하면이 문제를 피할 수 있습니다. –

+0

그게 무슨 뜻이야? – Turakar