I'm trying to dynamically export the all the methods within a class to Lua like this
Class class = [NSProgress class];
// Create a protocol that inherits from JSExport and with all the public methods and properties of the class
const char *protocolName = class_getName(class);
Protocol *protocol = objc_allocateProtocol(protocolName);
protocol_addProtocol(protocol, objc_getProtocol("LuaExport"));
// Add the public methods of the class to the protocol
unsigned int methodCount, classMethodCount, propertyCount;
Method *methods, *classMethods;
objc_property_t *properties;
methods = class_copyMethodList(class, &methodCount);
for (unsigned int methodIndex = 0; methodIndex < methodCount; ++methodIndex) {
Method method = methods[methodIndex];
protocol_addMethodDescription(protocol, method_getName(method), method_getTypeEncoding(method), YES, YES);
}
classMethods = class_copyMethodList(object_getClass(class), &classMethodCount);
for (unsigned int methodIndex = 0; methodIndex < classMethodCount; ++methodIndex) {
Method method = classMethods[methodIndex];
protocol_addMethodDescription(protocol, method_getName(method), method_getTypeEncoding(method), YES, NO);
}
properties = class_copyPropertyList(class, &propertyCount);
for (unsigned int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) {
objc_property_t property = properties[propertyIndex];
unsigned int attributeCount;
objc_property_attribute_t *attributes = property_copyAttributeList(property, &attributeCount);
protocol_addProperty(protocol, property_getName(property), attributes, attributeCount, YES, YES);
free(attributes);
}
free(methods);
free(classMethods);
free(properties);
// Add the new protocol to the class
objc_registerProtocol(protocol);
class_addProtocol(class, protocol);
LuaContext *ctx = [LuaContext new];
ctx[@"ex"] = [NSProgress progressWithTotalUnitCount:123];
NSError *error = nil;
[ctx parse:@"print(ex.totalUnitCount)" error:&error];
XCTAssert( ! error, @"failed to load script: %@", error);
The problem is that the exported object is immediately released so that when the script is parsed an EXC_BAD_ACCESS error is thrown at random places where the the object is get back from the wrapper
/* ... */
id obj = (__bridge id)wrapper->instance;
/* ... */
By retaining the the object changing line 328 to wrapper->instance = (__bridge_retained void*)object; the snippet above runs ok, but there is the problem of when the object must be released.
My suggestion is to make the wrapper an object instead of a struct, that holds the reference to the user data, like its counterpart JSValue
/* store the object's user data */
_index = luaL_ref(state, LUA_REGISTRYINDEX);
/* retrieve the object */
lua_rawgeti(state, LUA_REGISTRYINDEX, _index);
/* dispose of the object's user data */
luaL_unref(state, LUA_REGISTRYINDEX, _index);
I'm trying to dynamically export the all the methods within a class to Lua like this
The problem is that the exported object is immediately released so that when the script is parsed an
EXC_BAD_ACCESSerror is thrown at random places where the the object is get back from the wrapperBy retaining the the object changing line 328 to
wrapper->instance = (__bridge_retained void*)object;the snippet above runs ok, but there is the problem of when the object must be released.My suggestion is to make the wrapper an object instead of a struct, that holds the reference to the user data, like its counterpart
JSValue