【问题标题】:Rust Cocoa - How to Iterate NSArrayRust Cocoa - 如何迭代 NSArray
【发布时间】:2021-11-19 07:06:18
【问题描述】:

brandonhamilton/image-capture-core-rsICCameraDevice.mediaFiles() 我可以得到NSArray::count()(来自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

我错过了什么?

谢谢?????????‍♂️

【问题讨论】:

标签: objective-c cocoa rust iterator nsarray


【解决方案1】:

你错过了.iter()

for media_file in cam_media_files.iter() {

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

这个 crate 到 NSFastEnumeration 的桥提供了iter(),它返回一个NSFastIterator。 (NSFastIterator 不是 Cocoa 类型。它是这个 crate 提供的用于将 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)

【讨论】:

【解决方案2】:

根据文档,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)) {
   // ...
}

【讨论】:

    【解决方案3】:

    我对Cocoa不是很了解,我只是给你一个路径,希望能帮助你找到解决方案。

    你使用 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 方法

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

    【讨论】:

    • 虽然这表明您可以使用 *mut Object 做更多的事情,但它并不能真正回答 OP 的问题。您是否建议发送消息来迭代数组?什么讯息?代码和输出会是什么样子?
    • 你好@kmdreko。是的,不是真正的答案。更多的是一种反思,一种想法。但是在答案而不是评论中更清楚地呈现。
    猜你喜欢
    • 2010-11-02
    • 2013-12-19
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 2022-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多