2个版本
使用旧的Rust 2015
0.0.2 | 2015年2月24日 |
---|---|
0.0.1 | 2015年1月11日 |
#27 在 #objective-c
117 每月下载量
用于 block
3KB
58 行
Objective-C运行时绑定和包装器,用于Rust。
消息对象
可以使用 msg_send!
宏通过Objective-C对象进行消息传递
let cls = class!(NSObject);
let obj: *mut Object = msg_send![cls, new];
let hash: usize = msg_send![obj, hash];
let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
// Even void methods must have their return type annotated
let _: () = msg_send![obj, release];
引用计数
rc
模块提供类似于ARC语义的工具,用于在Rust中处理Objective-C的引用计数对象。一个 StrongPtr
保留对象并在丢弃时释放对象。一个 WeakPtr
不会保留对象,但可以升级为 StrongPtr
,如果对象已被释放,则安全失败。
// StrongPtr will release the object when dropped
let obj = unsafe {
StrongPtr::new(msg_send![class!(NSObject), new])
};
// Cloning retains the object an additional time
let cloned = obj.clone();
autoreleasepool(|| {
// Autorelease consumes the StrongPtr, but won't
// actually release until the end of an autoreleasepool
cloned.autorelease();
});
// Weak references won't retain the object
let weak = obj.weak();
drop(obj);
assert!(weak.load().is_null());
声明类
可以使用 ClassDecl
结构声明类。然后在最终注册类之前可以添加实例变量和方法。
以下示例演示了如何声明一个名为 MyNumber
的类,该类有一个名为 _number
的 u32
ivar,以及一个返回它的 number
方法
let superclass = class!(NSObject);
let mut decl = ClassDecl::new("MyNumber", superclass).unwrap();
// Add an instance variable
decl.add_ivar::<u32>("_number");
// Add an ObjC method for getting the number
extern fn my_number_get(this: &Object, _cmd: Sel) -> u32 {
unsafe { *this.get_ivar("_number") }
}
unsafe {
decl.add_method(sel!(number),
my_number_get as extern fn(&Object, Sel) -> u32);
}
decl.register();
异常
默认情况下,如果 msg_send!
宏抛出异常,这将导致从Rust回滚,从而导致不安全、未定义的行为。然而,这个crate有一个名为 "exception"
的功能,当启用时,将每个 msg_send!
包装在 @try
/@catch
中,并在捕获到异常时引发恐慌,防止Objective-C回滚到Rust。
消息类型验证
Objective-C运行时包括对每个方法的编码,描述了参数和返回类型。这个crate可以利用这些编码来验证Rust中使用的类型是否与方法的编码匹配。
要使用此功能,请启用 "verify_message"
功能。启用此功能后,将为每次消息发送执行类型检查,这也要求所有消息的所有参数和返回值都实现 Encode
。
如果此要求过于繁重,或者您只想验证特定的消息,则可以调用特定选择器的 Message::verify_message
方法。
支持其他操作系统
可以使用 GNUstep Objective-C运行时 在Linux或*BSD上使用这些绑定。
无运行时依赖
~12KB