Rust Cocoa - 如何迭代 NSArray
Rust Cocoa - How to Iterate NSArray
来自 brandonhamilton/image-capture-core-rs
's ICCameraDevice.mediaFiles()
I can get the NSArray::count()
(from core-foundation-rs
) :
let cam_media_files = camera_device.mediaFiles();
println!(
NSArray::count(cam_media_files) // 123
);
但是如何迭代这个 Object
?
我已经尝试了几件事:
// for media_file in NSArray::array(nil, cam_media_files) {
// for media_file in NSArray::arrayWithObject(nil, cam_media_files) {
for media_file in cam_media_files {
println!(" media_file: {:?}", media_file);
}
所有结果都是这样的:
error[E0277]: `*mut Object` is not an iterator
--> src/image_capture_core_mod.rs:86:31
|
86 | for media_file in cam_media_files {
| ^^^^^^^^^^^^^^^ `*mut Object` is not an iterator
|
= help: the trait `Iterator` is not implemented for `*mut Object`
= note: required because of the requirements on the impl of `IntoIterator` for `*mut Object`
= note: required by `into_iter`
这里没什么用:
https://docs.rs/cocoa/0.24.0/cocoa/foundation/trait.NSArray.html
我错过了什么?
谢谢 ♂️
我不太了解Cocoa,我只是给你一条路,希望能帮助你找到解决办法。
您使用 let cam_media_files = camera_device.mediaFiles();
和 mediaFiles(self) -> id;
id 是什么?
pub type id = *mut runtime::Object;
关于 runtime::Object 的文档是 https://docs.rs/objc/0.2.7/objc/,您可以使用 msg_send! crate 调用 Cocoa 方法
let cls = class!(NSObject);
let obj: *mut Object = msg_send![cls, new];
let hash: usize = msg_send![obj, hash];
根据文档,NSArray
有一个 objectAtIndex
方法,所以这应该有效:
for idx in 0..NSArray::count (cam_media_files) {
let media_file = NSArray::objectAtIndex (cam_media_files, idx);
// ...
}
或者如果你想用迭代器来做:
for media_file in (0..NSArray::count (cam_media_files)).map (|idx| NSArray::objectAtIndex (cam_media_files, idx)) {
// ...
}
你错过了 .iter()
:
for media_file in cam_media_files.iter() {
在 ObjC 中,NSArray 实现了 NSFastEnumeration,这是 ObjC 实现其 for...in
语法的方式。
此 crate 与 NSFastEnumeration 的桥接提供 iter()
,其中 returns 和 NSFastIterator。 (NSFastIterator 不是 Cocoa 类型。这是这个板条箱提供的将 NSFastEnumeration 桥接到 Iterator 的东西。)
请注意,此 crate 将 NSFastEnumeration 应用于所有对象类型(这就是 id
的意思),即使那些未在 Cocoa 中实现 NSFastEnumeration 的对象类型。这意味着你可以迭代任何东西...但是如果Cocoa不支持它会在运行时崩溃,你不会得到编译时警告或错误:
let string = cam_media_files.objectAtIndex(0);
for x in string.iter() {} // *Crash* (NSString doesn't support this)
来自 brandonhamilton/image-capture-core-rs
's ICCameraDevice.mediaFiles()
I can get the NSArray::count()
(from core-foundation-rs
) :
let cam_media_files = camera_device.mediaFiles();
println!(
NSArray::count(cam_media_files) // 123
);
但是如何迭代这个 Object
?
我已经尝试了几件事:
// for media_file in NSArray::array(nil, cam_media_files) {
// for media_file in NSArray::arrayWithObject(nil, cam_media_files) {
for media_file in cam_media_files {
println!(" media_file: {:?}", media_file);
}
所有结果都是这样的:
error[E0277]: `*mut Object` is not an iterator
--> src/image_capture_core_mod.rs:86:31
|
86 | for media_file in cam_media_files {
| ^^^^^^^^^^^^^^^ `*mut Object` is not an iterator
|
= help: the trait `Iterator` is not implemented for `*mut Object`
= note: required because of the requirements on the impl of `IntoIterator` for `*mut Object`
= note: required by `into_iter`
这里没什么用: https://docs.rs/cocoa/0.24.0/cocoa/foundation/trait.NSArray.html
我错过了什么?
谢谢 ♂️
我不太了解Cocoa,我只是给你一条路,希望能帮助你找到解决办法。
您使用 let cam_media_files = camera_device.mediaFiles();
和 mediaFiles(self) -> id;
id 是什么?
pub type id = *mut runtime::Object;
关于 runtime::Object 的文档是 https://docs.rs/objc/0.2.7/objc/,您可以使用 msg_send! crate 调用 Cocoa 方法
let cls = class!(NSObject);
let obj: *mut Object = msg_send![cls, new];
let hash: usize = msg_send![obj, hash];
根据文档,NSArray
有一个 objectAtIndex
方法,所以这应该有效:
for idx in 0..NSArray::count (cam_media_files) {
let media_file = NSArray::objectAtIndex (cam_media_files, idx);
// ...
}
或者如果你想用迭代器来做:
for media_file in (0..NSArray::count (cam_media_files)).map (|idx| NSArray::objectAtIndex (cam_media_files, idx)) {
// ...
}
你错过了 .iter()
:
for media_file in cam_media_files.iter() {
在 ObjC 中,NSArray 实现了 NSFastEnumeration,这是 ObjC 实现其 for...in
语法的方式。
此 crate 与 NSFastEnumeration 的桥接提供 iter()
,其中 returns 和 NSFastIterator。 (NSFastIterator 不是 Cocoa 类型。这是这个板条箱提供的将 NSFastEnumeration 桥接到 Iterator 的东西。)
请注意,此 crate 将 NSFastEnumeration 应用于所有对象类型(这就是 id
的意思),即使那些未在 Cocoa 中实现 NSFastEnumeration 的对象类型。这意味着你可以迭代任何东西...但是如果Cocoa不支持它会在运行时崩溃,你不会得到编译时警告或错误:
let string = cam_media_files.objectAtIndex(0);
for x in string.iter() {} // *Crash* (NSString doesn't support this)