Documentation ¶
Overview ¶
Package objc is a low-level pure Go objective-c runtime. This package is easy to use incorrectly, so it is best to use a wrapper that provides the functionality you need in a safer way.
Index ¶
- Variables
- func Send[T any](id ID, sel SEL, args ...any) T
- func SendSuper[T any](id ID, sel SEL, args ...any) T
- type Class
- func (c Class) AddIvar(name string, ty interface{}, types string) booldeprecated
- func (c Class) AddMethod(name SEL, imp IMP, types string) bool
- func (c Class) AddProtocol(protocol *Protocol) bool
- func (c Class) InstanceSize() uintptr
- func (c Class) InstanceVariable(name string) Ivar
- func (c Class) Register()deprecated
- func (c Class) SuperClass() Class
- type ID
- type IMP
- type Ivar
- type Protocol
- type SEL
- type Selector
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var MismatchError = errors.New("go struct doesn't match objective-c struct")
MismatchError occurs when the Go struct definition doesn't match that of Objective-C
var TagFormatError = errors.New(`objc tag doesn't match "ClassName : SuperClassName <Protocol, ...>""`)
TagFormatError occurs when the parser fails to parse the objc tag in a Selector object
Functions ¶
func Send ¶
Send is a convenience method for sending messages to objects that can return any type. This function takes a SEL instead of a string since RegisterName grabs the global Objective-C lock. It is best to cache the result of RegisterName.
Types ¶
type Class ¶
type Class uintptr
Class is an opaque type that represents an Objective-C class.
func AllocateClassPair
deprecated
AllocateClassPair creates a new class and metaclass. Then returns the new class, or Nil if the class could not be created
Deprecated: use RegisterClass instead
Example ¶
package main import ( "fmt" "github.com/ebitengine/purego/objc" ) func main() { var class = objc.AllocateClassPair(objc.GetClass("NSObject"), "FooObject", 0) class.AddMethod(objc.RegisterName("run"), objc.NewIMP(func(self objc.ID, _cmd objc.SEL) { fmt.Println("Hello World!") }), "v@:") class.Register() var fooObject = objc.ID(class).Send(objc.RegisterName("new")) fooObject.Send(objc.RegisterName("run")) }
Output: Hello World!
func GetClass ¶
GetClass returns the Class object for the named class, or nil if the class is not registered with the Objective-C runtime.
func RegisterClass ¶
RegisterClass takes a pointer to a struct that implements the Selector interface. It will register the structs fields and pointer receiver methods in the Objective-C runtime using the SEL returned from Selector. Any errors that occur trying to add a Method or Ivar is returned as an error. Such errors may occur in parsing or because the size of the struct does not match the size in Objective-C. If no errors occur then the returned Class has been registered successfully.
The struct's first field must be of type Class and have a tag that matches the format `objc:"ClassName : SuperClassName <Protocol, ...>`. This tag is equal to how the class would be defined in Objective-C.
func (Class) AddIvar
deprecated
AddIvar adds a new instance variable to a class. It may only be called after AllocateClassPair and before Register. Adding an instance variable to an existing class is not supported. The class must not be a metaclass. Adding an instance variable to a metaclass is not supported. It takes the instance of the type of the Ivar and a string representing the type.
Deprecated: use RegisterClass instead
Example ¶
package main import ( "fmt" "github.com/ebitengine/purego/objc" ) func main() { type barObject struct { isa objc.Class bar int } var class = objc.AllocateClassPair(objc.GetClass("NSObject"), "BarObject", 0) class.AddIvar("bar", int(0), "q") class.AddMethod(objc.RegisterName("bar"), objc.NewIMP(func(self *barObject, _cmd objc.SEL) int { return self.bar }), "q@:") class.AddMethod(objc.RegisterName("setBar:"), objc.NewIMP(func(self *barObject, _cmd objc.SEL, bar int) { self.bar = bar }), "v@:q") class.Register() var object = objc.ID(class).Send(objc.RegisterName("new")) object.Send(objc.RegisterName("setBar:"), 123) var bar = int(object.Send(objc.RegisterName("bar"))) fmt.Println(bar) }
Output: 123
func (Class) AddMethod ¶
AddMethod adds a new method to a class with a given name and implementation. The types argument is a string containing the mapping of parameters and return type. Since the function must take at least two arguments—self and _cmd, the second and third characters must be “@:” (the first character is the return type).
func (Class) AddProtocol ¶
AddProtocol adds a protocol to a class. Returns true if the protocol was added successfully, otherwise false (for example, the class already conforms to that protocol).
func (Class) InstanceSize ¶
InstanceSize returns the size in bytes of instances of the class or 0 if cls is nil
func (Class) InstanceVariable ¶
InstanceVariable returns an Ivar data structure containing information about the instance variable specified by name.
func (Class) SuperClass ¶
SuperClass returns the superclass of a class. You should usually use NSObject‘s superclass method instead of this function.
type ID ¶
type ID uintptr
ID is an opaque pointer to some Objective-C object
func (ID) Send ¶
Send is a convenience method for sending messages to objects. This function takes a SEL instead of a string since RegisterName grabs the global Objective-C lock. It is best to cache the result of RegisterName.
func (ID) SendSuper ¶
SendSuper is a convenience method for sending message to object's super. This function takes a SEL instead of a string since RegisterName grabs the global Objective-C lock. It is best to cache the result of RegisterName.
Example ¶
package main import ( "fmt" "github.com/ebitengine/purego/objc" ) func main() { super := objc.AllocateClassPair(objc.GetClass("NSObject"), "SuperObject", 0) super.AddMethod(objc.RegisterName("doSomething"), objc.NewIMP(func(self objc.ID, _cmd objc.SEL) { fmt.Println("In Super!") }), "v@:") super.Register() child := objc.AllocateClassPair(super, "ChildObject", 0) child.AddMethod(objc.RegisterName("doSomething"), objc.NewIMP(func(self objc.ID, _cmd objc.SEL) { fmt.Println("In Child") self.SendSuper(_cmd) }), "v@:") child.Register() objc.ID(child).Send(objc.RegisterName("new")).Send(objc.RegisterName("doSomething")) }
Output: In Child In Super!
type IMP ¶
type IMP uintptr
IMP is a function pointer that can be called by Objective-C code.
Example ¶
package main import ( "fmt" "github.com/ebitengine/purego" "github.com/ebitengine/purego/objc" ) func main() { imp := objc.NewIMP(func(self objc.ID, _cmd objc.SEL, a3, a4, a5, a6, a7, a8, a9 int) { fmt.Println("IMP:", self, _cmd, a3, a4, a5, a6, a7, a8, a9) }) purego.SyscallN(uintptr(imp), 105, 567, 9, 2, 3, ^uintptr(4), 4, 8, 9) }
Output: IMP: 105 567 9 2 3 -5 4 8 9
func NewIMP ¶
func NewIMP(fn interface{}) IMP
NewIMP takes a Go function that takes (ID, SEL) as its first two arguments. ID may instead be a pointer to a struct whose first field has type Class. It returns an IMP function pointer that can be called by Objective-C code. The function pointer is never deallocated.
type Ivar ¶
type Ivar uintptr
Ivar an opaque type that represents an instance variable.
type Protocol ¶
type Protocol uintptr
Protocol is a type that declares methods that can be implemented by any class.
func GetProtocol ¶
GetProtocol returns the protocol for the given name or nil if there is no protocol by that name.
type SEL ¶
type SEL uintptr
SEL is an opaque type that represents a method selector
func RegisterName ¶
RegisterName registers a method with the Objective-C runtime system, maps the method name to a selector, and returns the selector value. This function grabs the global Objective-c lock. It is best the cache the result of this function.