Skip to content

Instantly share code, notes, and snippets.

@rweichler
Created November 25, 2017 04:59
Show Gist options
  • Select an option

  • Save rweichler/be1c8577b86f4da8ba494732302f7b4c to your computer and use it in GitHub Desktop.

Select an option

Save rweichler/be1c8577b86f4da8ba494732302f7b4c to your computer and use it in GitHub Desktop.
local objc = require 'objc'
local ffi = require 'ffi'
local count = 0
function objc.GenerateClass(super, ...)
super = super or 'NSObject'
count = count + 1
local name = 'EQEAPP_'..count..super
if ... then
objc.class(name, super..'<'..table.concat({...}, ',')..'>')
else
objc.class(name, super)
end
return objc[name]
end
local key = ffi.new('int[1]')
function objc.ref(obj, set)
-- associated objects should be objc
-- objects. but this works, so w/e
assert(set)
local ref = REF(set, true)
local v = ffi.cast('int *', C.malloc(ffi.sizeof('int')))
v[0] = ref
C.objc_setAssociatedObject(obj, key, ffi.cast('id', v), C.OBJC_ASSOCIATION_ASSIGN)
end
function objc.unref(obj)
local v = ffi.cast('int *', C.objc_getAssociatedObject(obj, key))
if not v then error('obj not found') end
REF(v[0], false)
C.objc_setAssociatedObject(obj, key, nil, C.OBJC_ASSOCIATION_ASSIGN)
C.free(v)
end
function objc.getref(obj)
local v = ffi.cast('int *', C.objc_getAssociatedObject(obj, key))
return v and REF(v[0], nil) or nil
end
local vc_class = objc.GenerateClass('UIViewController')
local function dealloc(m)
local self = objc.getref(m)
for _,v in pairs(self.i) do
local type = type(v)
if type == 'cdata' then
v:release()
elseif type == 'table' and v.m then
v.m:release()
end
end
if self.dealloc then
self:dealloc()
end
objc.unref(m)
objc.callsuper(m, 'dealloc')
end
dealloc = ffi.cast('IMP', ffi.cast('void (*)(id, SEL)', dealloc))
C.class_replaceMethod(vc_class, objc.SEL('dealloc'), dealloc, ffi.arch == 'arm64' and 'v16@0:8' or 'v8@0:4')
local function viewDidLoad(m)
local self = objc.getref(m)
return self.on_load(m)
end
viewDidLoad = ffi.cast('IMP', ffi.cast('void (*)(id, SEL)', viewDidLoad))
C.class_replaceMethod(vc_class, objc.SEL('viewDidLoad'), viewDidLoad, ffi.arch == 'arm64' and 'v16@0:8' or 'v8@0:4')
function VIEWCONTROLLER(callback, title)
local self = {}
self.i = {}
self.m = vc_class:alloc():init()
self.on_load = callback
self.m:setTitle(title or '')
objc.ref(self.m, self)
self.m:autorelease()
return self.m
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment