루아 5.1에서 테이블에 대해 __gc
메서드를 사용할 수 없다는 문제에 현재 직면하고 있습니다. 루아 5.2에서 구현되었으므로 현재이 문제가 발생합니다. 그러나 루아 표가 수집되면 할당 된 원시 자원을 릴리스하려고합니다. Lua 5.1 용 Lua 5.2에서 __gc
metamethod의 기능을 제공하는 해결 방법을 만들 수 있습니까?Lua 5.1 테이블에 대한 __gc 메타 메서드에 대한 해결 방법
답변
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)
이
참고 루아 5.2 이상 나중에 테이블에서 __gc
이 공식적으로 지원되므로 newproxy
이 더 이상 없습니다.
제안 된 솔루션을 사용할 때 우려 할 사항이 하나 있습니다. - 쌍을 기준으로 테이블을 탐색하면() 하나의 추가 키가 생깁니다. 원본 테이블 대신 적절한 메타 메서드를 사용하여 프록시 개체를 사용하면이 문제를 피할 수 있습니다. –
그게 무슨 뜻이야? – Turakar
테이블에 프록시 개체를 사용하고 '__gc' 메타 메서드를 그 테이블에 넣습니다. 테이블이 수집되면 프록시가 수집되고'__gc' 메소드가 호출됩니다. 이것은 추가 gc주기가 필요할 수 있습니다. –