Rust Cocoa - 如何制作 NSDictionary?

Posted

技术标签:

【中文标题】Rust Cocoa - 如何制作 NSDictionary?【英文标题】:Rust Cocoa - How to make an NSDictionary? 【发布时间】:2021-11-07 00:44:11 【问题描述】:

我一直在阅读以试图理解它。你可以在这里看到dictionaryWithObjects:objects 需要一个对象和键数组:

NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
                                                       forKeys:keys
                                                         count:count];

https://developer.apple.com/documentation/foundation/nsdictionary#overview


但是initWithObjectsAndKeys_ 只有一个输入对象? ??????????‍♂️

unsafe fn initWithObjectsAndKeys_(self, firstObject: *mut Object) -> *mut Object

https://docs.rs/cocoa/0.24.0/cocoa/foundation/trait.NSDictionary.html#tymethod.initWithObjectsAndKeys_

【问题讨论】:

【参考方案1】:

许多 Rust 可可 API 是底层 Objective-C API 的直接包装器,例如 initWithObjectsAndKeys:https://developer.apple.com/documentation/foundation/nsdictionary/1574190-initwithobjectsandkeys?language=objc。调用者需要传递一个指针,该指针指向以 null 结尾的数组的第一个元素,该数组包含字典的交替值和键元素。

【讨论】:

当你的值/“对象”不是同一类型 (String) 时会发生什么?以本词典为例:github.com/Joride/Monarch/blob/main/ViewController.swift#L105 来自 GitHub 上的 Josh 线程:通常,objc 类型共享 id 类型的底层表示(例如 github.com/servo/core-foundation-rs/blob/master/…),因此您需要一个 ids 的向量。【参考方案2】:

在 Objective C 中,您可以像这样调用 initWithObjectsAndKeys

NSMutableDictionary *aDictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                    @"Value1", @"Key1",
                                    @"Value2", @"Key2",
                                    @"Value3", @"Key3",
                                    nil, nil
];

(从技术上讲,一个 nil 就足够了,但我发现它缺乏对称性,所以我放了两个 :-P)

这是一个可变参数函数,可以接受多个参数。

恐怕我对 Rust 的了解还不够,无法知道它是否可以以同样的方式处理事情。

【讨论】:

【参考方案3】:

当然,在从这里的精彩答案中学习了如何做到这一点之后(以及在发布这个问题之前,在未公开的时间内搜索 repo、所有 GitHub 和网络),我在 a来自@Josh Matthews servo/core-foundation-rs 库的测试:

let mkstr = |s| unsafe  NSString::alloc(nil).init_str(s) ;
let keys = vec!["a", "b", "c", "d", "e", "f"];
let objects = vec!["1", "2", "3", "4", "5", "6"];

unsafe 
               
  let keys_raw_vec = keys.clone().into_iter().map(&mkstr).collect::<Vec<_>>();
  let objs_raw_vec = objects.clone().into_iter().map(&mkstr).collect::<Vec<_>>();

  let keys_array = NSArray::arrayWithObjects(nil, &keys_raw_vec);
  let objs_array = NSArray::arrayWithObjects(nil, &objs_raw_vec);

  let dict = NSDictionary::dictionaryWithObjects_forKeys_(nil, objs_array, keys_array);

来自https://github.com/servo/core-foundation-rs/blob/355740417e69d3b1a8d909f84d91a6618c9721cc/cocoa-foundation/tests/foundation.rs#L145

【讨论】:

以上是关于Rust Cocoa - 如何制作 NSDictionary?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cocoa 和 CGDisplayCreateImageForRect 在 Mac OS X 中截取区域截图?

如何在 Cocoa 应用程序中切换视图?

Cocoa 查看自动缩放内容

在 Cocoa/Interface Builder 中,单击按钮后如何清除文本字段中的文本

如何创建值可以是多种类型之一的 Rust HashMap?

在没有 Xcode 的情况下制作 Cocoa App,例如:使用 VIM 进行编辑和 Swift 编译器