Rust Cocoa - 如何迭代 NSArray

Rust Cocoa - How to Iterate NSArray

提问人:Mikeumus 提问时间:9/27/2021 最后编辑:Mikeumus 更新时间:9/28/2021 访问量:328

问:

brandonhamilton/image-capture-core-rs 中我可以得到(从 core-foundation-rs):ICCameraDevice.mediaFiles()NSArray::count()

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

我错过了什么?

谢谢 🙇🏻 ♂️

Objective-C Cocoa Rust 迭代器 nsarray

评论

1赞 El Tomato 9/27/2021
objective-c 标签有什么用?
0赞 Mikeumus 9/27/2021
@ElTomato这是 Rust 调用 ObjC,一个 C 桥:github.com/brandonhamilton/image-capture-core-rs/blob/master/......
1赞 Stargateur 9/27/2021
我想 docs.rs/cocoa/0.24.0/cocoa/foundation/...,你的问题很不清楚,板条箱有 zéro doc

答:

1赞 Zeppi 9/27/2021 #1

我不太了解可可,我只是给你一条路,希望能帮助你找到解决方案。

您使用 do 和let cam_media_files = camera_device.mediaFiles();mediaFiles(self) -> id;

Wath 是 id?

pub type id = *mut runtime::Object;

关于runtime::Object的文档 https://docs.rs/objc/0.2.7/objc/,您可以使用msg_send!crate 调用 Cocoa methode

let cls = class!(NSObject);
let obj: *mut Object = msg_send![cls, new];
let hash: usize = msg_send![obj, hash];

评论

0赞 kmdreko 9/27/2021
虽然这表明你可以用 做更多的事情,但它并没有真正回答 OP 的问题。您是否建议发送消息来迭代数组?什么信息?代码和输出会是什么样子?*mut Object
0赞 Zeppi 9/27/2021
你好@kmdreko。是的,不是真正的答案。更多的是一种反思,一种想法。但更清楚地呈现在答案而不是评论中。
3赞 Jmb 9/27/2021 #2

根据文档,有一个方法,所以这应该有效:NSArrayobjectAtIndex

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)) {
   // ...
}
4赞 Rob Napier 9/28/2021 #3

您缺少:.iter()

for media_file in cam_media_files.iter() {

在 ObjC 中,NSArray 实现了 NSFastEnumeration,这就是 ObjC 实现其语法的方式。for...in

此 crate 与 NSFastEnumeration 的桥提供 ,它返回一个 NSFastIterator。(NSFastIterator 不是 Cocoa 类型。这是此 crate 提供的东西,用于将 NSFastEnumeration 桥接到 Iterator。iter()

请注意,此 crate 将 NSFastEnumeration 应用于所有对象类型(这就是意思),即使是那些没有在 Cocoa 中实现 NSFastEnumeration 的对象类型。这意味着你可以迭代任何东西......但如果 Cocoa 不支持它,它会在运行时崩溃,并且您不会收到编译时警告或错误:id

let string = cam_media_files.objectAtIndex(0);
for x in string.iter() {} // *Crash* (NSString doesn't support this)

评论

0赞 Mikeumus 9/28/2021
嗨,@Rob纳皮尔,谢谢你的回答。添加错误:.不过我还是来看看吧!🙂iter()^^^^ method not found in *mut ObjectNSFastEnumeration
1赞 Rob Napier 9/28/2021
我用可可 0.24 测试了这一点,并且 .您有我们可以测试的小项目吗?gist.github.com/rust-play/97ba551bd1eb5bb13fc2298c4b2603c5use cocoa::base::*use cocoa::foundation::*
0赞 Mikeumus 10/1/2021
ICCameraDevice.mediaFiles()返回 : developer.apple.com/documentation/imagecapturecore/...查看 github.com/brandonhamilton/image-capture-core-rs/blob/master/...我不知道这是否仍然适用于?[ICCameraItem]?iter