objc_util
Objective-C Runtime 调用与系统框架访问。
Objective-C Runtime 访问层:调用系统类、selector、Foundation/UIKit 对象与 block。
边界:高级能力入口;拍照、网络、定位等优先用已封装模块。UIKit 调用须@on_main_thread;block 回调用retain_global保活。
#模块概览
| 项 | 说明 |
|---|---|
| 导入 | from objc_util import ObjCClass, ns, on_main_thread, ... |
| 适合做什么 | 访问未封装系统 API、转换 ObjC 对象、创建 block |
| 调用时机 | UI 相关放主线程;长期回调对象要保活 |
| 推荐顺序 | 确认无公开模块 → ObjCClass → 调用 selector |
| Selector | Python 方法名中 _ 对应 ObjC 的 : |
#快速开始
读取设备信息:
已复制
from objc_util import ObjCClass
UIDevice = ObjCClass("UIDevice")
device = UIDevice.currentDevice()
print(device.name())
print(device.systemVersion())
Python 对象转 Objective-C:
已复制
from objc_util import ObjCClass, ns, nsurl
payload = ns({"name": "Ada", "level": 3})
url = nsurl("https://www.python.org")
print(url.absoluteString())
#AppUI 示例
通过 Runtime 读取设备名(只读、放按钮回调)。
已复制
import appui
from objc_util import ObjCClass, on_main_thread
state = appui.State(
device_name="—",
os_version="—",
status="点击读取",
)
@on_main_thread
def read_device():
UIDevice = ObjCClass("UIDevice")
device = UIDevice.currentDevice()
state.device_name = str(device.name())
state.os_version = str(device.systemVersion())
state.status = "已读取"
def body():
return appui.NavigationStack(
appui.Form([
appui.Section("设备", [
appui.Button("读取设备信息", action=read_device)
.button_style("bordered_prominent"),
]),
appui.Section("结果", [
appui.LabeledContent("名称", value=state.device_name),
appui.LabeledContent("系统", value=state.os_version),
appui.Text(state.status).foreground_color("secondaryLabel"),
]),
]).navigation_title("ObjC Runtime")
)
appui.run(body, state=state)
#API 参考
#速查
| 分组 | API |
|---|---|
| Runtime | ObjCClass、ObjCInstance、sel、load_framework |
| 转换 | ns(py_obj)、nsurl(url_or_path)、nsdata_to_bytes、uiimage_to_png |
| 线程 | on_main_thread(func) |
| 生命周期 | retain_global(obj)、release_global(obj) |
| Block | ObjCBlock(func, restype=None, argtypes=None) |
| 结构体 | CGPoint、CGRect、CGSize、UIEdgeInsets、NSRange 等 |
#ObjCClass 与 selector
已复制
NSDictionary = ObjCClass("NSDictionary")
obj = NSDictionary.dictionaryWithObject_forKey_("value", "key")
# 对应 dictionaryWithObject:forKey:
#主线程
已复制
from objc_util import ObjCClass, on_main_thread
UIColor = ObjCClass("UIColor")
@on_main_thread
def blue():
return UIColor.systemBlueColor()
#常用转换
| 函数 | 用途 |
|---|---|
ns({"a": 1}) | dict/list/str → Foundation 对象 |
nsurl("https://...") | 创建 NSURL |
nsdata_to_bytes(data) | NSData → bytes |
#常见错误
| 错误写法 | 后果 | 修正 |
|---|---|---|
| 未封装能力直接用 Runtime | 脆弱、难维护 | 优先 photos、network 等 |
| UIKit 非主线程调用 | 崩溃或无效 | @on_main_thread |
block 未 retain_global | 回调失效 | 保活到流程结束 |
| 猜测 selector 签名 | 运行时错误 | 对照 Apple 文档逐项验证 |
| 调用私有 API | 审核风险 | 仅用公开 API |
#相关文档
#预期效果
运行示例后,界面应出现文档描述的目标结果;若与预期不符,先看「失败路径」并按返回值或日志排查。