Documentation
¶
Overview ¶
Package objc provides cached Objective-C runtime helpers.
Package objc provides cached Objective-C runtime helpers.
This package wraps purego/objc to provide selector caching for better performance.
Index ¶
- Variables
- func AddExceptionHandler(fn func(exception ID, context unsafe.Pointer)) uintptr
- func AddMethod(cls Class, sel SEL, impl any, types string) bool
- func CallWithError(id ID, sel SEL, args ...any) error
- func CleanupExceptionHandler()
- func ConvertSlice[T any](ids []ID, convert func(ID) T) []T
- func ConvertSliceToStrings(ids []ID) []string
- func DisableDefaultExceptionHandler()
- func EnableDefaultExceptionHandler()
- func EnableExceptionLogging()
- func GoString(cstr *byte) string
- func IDToString(id ID) string
- func MustSend[T any](id ID, sel SEL, args ...any) T
- func NewActionTarget(owner ID, fn func(sender ID)) (target ID, sel SEL)
- func RegisterClassPair(cls Class)
- func RemoveExceptionHandler(token uintptr)
- func RespondsToSelector(id ID, sel SEL) bool
- func SafeSend[T any](id ID, sel SEL, args ...any) (T, error)
- func Send[T any](id ID, sel SEL, args ...any) T
- func SendWithError[T any](id ID, sel SEL, args ...any) (T, error)
- func SetExceptionPreprocessor(fn ExceptionPreprocessorFunc)
- func SetUncaughtExceptionHandler(handler ExceptionHandler)
- func SetupExceptionHandler(config ExceptionHandlerConfig) error
- type Block
- type CArrayArg
- type Class
- type ExceptionHandler
- type ExceptionHandlerConfig
- type ExceptionPreprocessorFunc
- type FieldDef
- type ID
- type IDGetter
- type MethodDef
- type ObjCException
- type Protocol
- type SEL
- type UnrecognizedSelectorError
Constants ¶
This section is empty.
Variables ¶
var ( // Exception handler masks (from ExceptionHandling framework) // These are defined here so we don't need the generated bindings NSLogUncaughtExceptionMask uint = 1 << 0 NSHandleUncaughtExceptionMask uint = 1 << 1 NSLogUncaughtSystemExceptionMask uint = 1 << 2 NSHandleUncaughtSystemExceptionMask uint = 1 << 3 NSLogUncaughtRuntimeErrorMask uint = 1 << 4 NSHandleUncaughtRuntimeErrorMask uint = 1 << 5 NSLogTopLevelExceptionMask uint = 1 << 6 NSHandleTopLevelExceptionMask uint = 1 << 7 NSLogOtherExceptionMask uint = 1 << 8 NSHandleOtherExceptionMask uint = 1 << 9 )
var ErrUnrecognizedSelector = &UnrecognizedSelectorError{}
ErrUnrecognizedSelector is returned when an object does not respond to a selector.
Functions ¶
func AddExceptionHandler ¶
AddExceptionHandler adds a low-level exception handler using objc_addExceptionHandler. This is called during exception unwinding and cannot prevent the crash, but can capture exception information.
Returns a token that can be passed to RemoveExceptionHandler. Note: This is macOS-only (not available on iOS).
func CallWithError ¶
CallWithError calls a void-returning selector and handles the NSError** pattern.
func CleanupExceptionHandler ¶
func CleanupExceptionHandler()
CleanupExceptionHandler removes any configured exception handlers.
func ConvertSlice ¶
ConvertSlice maps []ID to []T using a converter function.
func ConvertSliceToStrings ¶
ConvertSliceToStrings maps []ID to []string via IDToString.
func DisableDefaultExceptionHandler ¶
func DisableDefaultExceptionHandler()
DisableDefaultExceptionHandler removes both the exception preprocessor and the uncaught exception handler, reverting to the default ObjC runtime behavior (abort on uncaught exceptions). This is useful if you want to handle exceptions entirely through your own mechanism or prefer raw SIGABRT crashes for a debugger.
func EnableDefaultExceptionHandler ¶
func EnableDefaultExceptionHandler()
EnableDefaultExceptionHandler enables the default exception handler that prints diagnostic information to stderr and exits cleanly. This is called automatically by init(). The preprocessor is also installed so that exceptions are intercepted before the C++ runtime calls abort().
To replace the default behavior, call SetExceptionPreprocessor or SetUncaughtExceptionHandler with a non-nil handler. To disable exception handling entirely, call DisableDefaultExceptionHandler.
func EnableExceptionLogging ¶
func EnableExceptionLogging()
EnableExceptionLogging enables automatic logging of all Objective-C exceptions before they are thrown. Useful for debugging.
func GoString ¶
GoString converts a C string (*byte from UTF8String) to a Go string. This is needed because UTF8String returns const char*, not an ObjC object.
func MustSend ¶
MustSend calls a selector and panics with a clear error if the object doesn't respond. Use this when you expect the selector to always exist but want a clearer panic message than the NSInvalidArgumentException.
func NewActionTarget ¶
NewActionTarget creates an Objective-C trampoline object that calls fn when it receives the "invoke:" selector. The trampoline is associated with owner via objc_setAssociatedObject so it is retained for the owner's lifetime and cleaned up automatically when the owner is deallocated or a new action target replaces it.
Returns the trampoline ID and the selector to wire as the action.
func RegisterClassPair ¶
func RegisterClassPair(cls Class)
RegisterClassPair registers a class pair with the runtime.
func RemoveExceptionHandler ¶
func RemoveExceptionHandler(token uintptr)
RemoveExceptionHandler removes an exception handler added by AddExceptionHandler.
func RespondsToSelector ¶
RespondsToSelector checks if an object responds to the given selector. This is the safe way to check before calling a method.
func SafeSend ¶
SafeSend calls a selector only if the object responds to it. Returns the zero value and ErrUnrecognizedSelector if the selector is not recognized. This prevents NSInvalidArgumentException crashes from unrecognized selectors.
func Send ¶
Send calls purego.Send with the given arguments. If any argument implements IDGetter (has GetID() method), the ID is automatically extracted. This allows passing struct wrappers like VZVirtualMachine directly instead of having to call .ID or .GetID() manually. Nil interface values are converted to ID(0) to avoid purego panics. When T is []ID, the return value from the ObjC call (an NSArray) is automatically converted to a Go slice via NSArrayToSlice.
func SendWithError ¶
SendWithError calls a selector handles the NSError** pattern. It assumes the method accepts an NSError** as its last argument. It automatically appends the error pointer to the arguments.
func SetExceptionPreprocessor ¶
func SetExceptionPreprocessor(fn ExceptionPreprocessorFunc)
SetExceptionPreprocessor sets a custom function that is called before any Objective-C exception is thrown. This can be used for logging and debugging.
Passing nil restores the default behavior (handleException + os.Exit(1)).
NOTE: The preprocessor cannot prevent the exception in pure Go - the program will still crash. For actual exception catching, use the cgoexception subpackage.
Example:
objc.SetExceptionPreprocessor(func(exc objc.ID) objc.ID {
info := objc.GetExceptionInfo(exc)
fmt.Printf("Exception about to throw: %s\n", info.Name)
return exc
})
func SetUncaughtExceptionHandler ¶
func SetUncaughtExceptionHandler(handler ExceptionHandler)
SetUncaughtExceptionHandler registers a custom handler for uncaught Objective-C exceptions.
IMPORTANT: Objective-C exceptions cannot be recovered from in Go. This handler is called just before the program terminates, giving you a chance to:
- Log diagnostic information
- Write crash reports
- Clean up resources
The handler receives:
- name: The exception name (e.g., "NSInvalidArgumentException")
- reason: The exception reason (e.g., "-[NSObject fakeMethod]: unrecognized selector")
- callStack: The Objective-C call stack symbols
Example:
objc.SetUncaughtExceptionHandler(func(name, reason string, callStack []string) {
fmt.Fprintf(os.Stderr, "Objective-C Exception: %s\n", name)
fmt.Fprintf(os.Stderr, "Reason: %s\n", reason)
for _, frame := range callStack {
fmt.Fprintf(os.Stderr, " %s\n", frame)
}
})
func SetupExceptionHandler ¶
func SetupExceptionHandler(config ExceptionHandlerConfig) error
SetupExceptionHandler configures exception handling using the most effective available mechanism. This uses NSExceptionHandler with a delegate to intercept exceptions via purego.
Example:
objc.SetupExceptionHandler(objc.ExceptionHandlerConfig{
LogExceptions: true,
OnException: func(exc *objc.ObjCException) {
fmt.Printf("Exception: %s\n", exc.Name)
},
})
Types ¶
type CArrayArg ¶
type CArrayArg struct {
// contains filtered or unexported fields
}
CArrayArg marks a Go slice argument that should be passed to Objective-C as a pointer to contiguous C array storage.
Use CArray at call sites for APIs that take `*T` and a paired `count` parameter.
type Class ¶
Type aliases for convenience
func RegisterClass ¶
func RegisterClass(name string, superClass Class, protocols []*Protocol, ivars []FieldDef, methods []MethodDef) (Class, error)
RegisterClass registers a new Objective-C class with the runtime. The class inherits from superClass and implements the given protocols. ivars defines instance variables, methods defines the class methods.
type ExceptionHandler ¶
ExceptionHandler is called when an uncaught Objective-C exception occurs. The handler receives the exception name, reason, and call stack. Note: The program will terminate after this handler returns - recovery is not possible.
type ExceptionHandlerConfig ¶
type ExceptionHandlerConfig struct {
// LogExceptions enables automatic logging of all exceptions
LogExceptions bool
// UseNSExceptionHandler enables the NSExceptionHandler delegate approach
// This provides more control but requires the ExceptionHandling framework
UseNSExceptionHandler bool
// ExceptionHandlingMask sets which exception types to handle (if UseNSExceptionHandler)
// Use constants: NSLogUncaughtExceptionMask, NSHandleUncaughtExceptionMask, etc.
ExceptionHandlingMask uint
// OnException is called when an exception is detected (before crash)
OnException func(exc *ObjCException)
}
ExceptionHandlerConfig configures how exceptions are handled.
type ExceptionPreprocessorFunc ¶
ExceptionPreprocessorFunc is called before any Objective-C exception is thrown. This allows logging/debugging but cannot prevent the exception in pure Go. For actual exception catching, use the cgoexception subpackage.
type ID ¶
Type aliases for convenience
func GetLastException ¶
func GetLastException() ID
GetLastException returns the last exception seen by the preprocessor.
func NSArrayToSlice ¶
NSArrayToSlice converts an NSArray ID into a []ID by calling count and objectAtIndex:.
type IDGetter ¶
type IDGetter interface {
GetID() ID
}
IDGetter is implemented by types that wrap an Objective-C object ID. This allows objc.Send to automatically extract the ID from wrapper types.
type ObjCException ¶
type ObjCException struct {
Name string // Exception name (e.g., "NSInvalidArgumentException")
Reason string // Exception reason/message
CallStack []string // Objective-C call stack symbols
// contains filtered or unexported fields
}
ObjCException represents an Objective-C exception.
func GetExceptionInfo ¶
func GetExceptionInfo(exception ID) *ObjCException
GetExceptionInfo extracts information from an NSException object.
func (*ObjCException) Error ¶
func (e *ObjCException) Error() string
Error implements the error interface.
func (*ObjCException) Exception ¶
func (e *ObjCException) Exception() ID
Exception returns the underlying NSException ID.
type Protocol ¶
Type aliases for convenience
func GetProtocol ¶
GetProtocol returns the protocol with the given name, or nil if not found.
type SEL ¶
Type aliases for convenience
func RegisterName ¶
RegisterName registers a selector with the Objective-C runtime. This is the same as Sel but without caching - use Sel for repeated calls.
type UnrecognizedSelectorError ¶
type UnrecognizedSelectorError struct {
Selector string
}
UnrecognizedSelectorError indicates an object does not respond to a selector.
func (*UnrecognizedSelectorError) Error ¶
func (e *UnrecognizedSelectorError) Error() string