- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 Clang 的原始装箱功能将枚举成员打包到 NSNumber
Boxed Enums section关于此的 Clang 文档的一部分说编译器将枚举成员装箱为整数,除非指定了类型。
有趣的是,根据我将枚举成员传递给方法的方式,我得到了不同大小的整数。我已经能够将案例隔离为以下代码
typedef enum _MyEnum {
MyEnumMember1 = 1000
} MyEnum;
- (void)testEnumerationBoxing
{
NSNumber *numberA = [self testA];
NSNumber *numberB = [self testB:MyEnumMember1];
CFNumberType numberTypeA = CFNumberGetType((__bridge CFNumberRef) numberA);
CFNumberType numberTypeB = CFNumberGetType((__bridge CFNumberRef) numberB);
NSLog(@"CF Number type for A: %lu; B: %lu", numberTypeA, numberTypeB);
}
- (NSNumber *)testA
{
return @(MyEnumMember1);
}
- (NSNumber *)testB:(MyEnum)enumMember
{
return @(enumMember);
}
控制台输出为
CF Number type for A: 3; B: 4
(第一个是kCFNumberSInt32Type
,第二个是kCFNumberSInt64Type
)
如果我将声明更改为 typedef enum _MyEnum : int
,我会看到两者的结果相同:kCFNumberSInt32Type
。
为什么两种装箱方式的整数大小不同?
最佳答案
我认为您提供的链接中描述了这种情况:
Boxing a value of enum type will result in a NSNumber pointer with a creation method according to the underlying type of the enum, which can be a fixed underlying type or a compiler-defined integer type capable of representing the values of all the members of the enumeration:
typedef enum : unsigned char { Red, Green, Blue } Color;
Color col => Red;
NSNumber *nsCol = @(col); // => [NSNumber numberWithUnsignedChar:]
但图书馆促销的细节没有涉及,这就是引入预期差异的地方。
-testA
结束调用 +[NSNumber numberWithInt:]
-testB
结束调用 +[NSNumber numberWithUnsignedInt:]
所以您看到的抽象“提升”是因为 CFNumber
(因此 NSNumber
)此时实际上不支持无符号值(参见 CFNumberType 的常量
枚举)——根据您看到的输出,然后假设 NSNumber
实现只是提升到下一个能够表示构造函数的无符号初始值设定项的所有值的有符号类型-- 显然没有测试该值以查看是否可以应用任何“宽度最小化”。
当然,NSNumber
声明了将无符号类型作为参数的构造函数和初始化器,但无符号整数的内部表示实际上存储为有符号整数表示。
在将装箱文字提升为 NSNumber
时,编译器似乎会调用适当/准确的便捷构造函数。例如,uint16_t
类型的枚举将存储为 32 位 int(通过 numberWithUnsignedShort:
),而 int32_t 也是 32 位 int(通过 numberWithInt:
)。虽然,在 -testA
的情况下,该值也是已知的,因此也可以在那里调用更合适的构造函数——因此编译器仅根据类型而不是类型和值进行宽度最小化。当枚举的类型未指定或指定为无符号类型时,您可能会看到这样的提升。
关于objective-c - 将相同的枚举成员装箱传递给方法时会产生更大的整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12071200/
Github:https://github.com/jjvang/PassIntentDemo 我一直在关注有关按 Intent 传递对象的教程:https://www.javacodegeeks.c
我有一个 View ,其中包含自动生成的 text 类型的 input 框。当我单击“通过电子邮件发送结果”按钮时,代码会将您带到 CalculatedResults Controller 中的 Em
我有一个基本的docker镜像,我将以此为基础构建自己的镜像。我没有基础镜像的Dockerfile。 基本上,基本镜像使用两个--env arg,一个接受其许可证,一个选择在容器中激活哪个框架。我可以
假设我想计算 2^n 的总和,n 范围从 0 到 100。我可以编写以下内容: seq { 0 .. 100 } |> Seq.sumBy ((**) 2I) 但是,这与 (*) 或其他运算符/函数不
我有这个网址: http://www.example.com/get_url.php?ID=100&Link=http://www.test.com/page.php?l=1&m=7 当我打印 $_G
我想将 window.URL.createObjectURL(file) 创建的地址传递给 dancer.js 但我得到 GET blob:http%3A//localhost/b847c5cd-aa
我想知道如何将 typedef 传递给函数。例如: typedef int box[3][3]; box empty, *board[3][3]; 我如何将 board 传递给函数?我
我正在将一些代码从我的 Controller 移动到核心数据应用程序中的模型。 我编写了一个方法,该方法为我定期发出的特定获取请求返回 NSManagedObjectID。 + (NSManagedO
为什么我不能将类型化数组传递到采用 any[] 的函数/构造函数中? typedArray = new MyType[ ... ]; items = new ko.observableArray(ty
我是一名新的 Web 开发人员,正在学习 html5 和 javascript。 我有一个带有“选项卡”的网页,可以使网页的某些部分消失并重新出现。 链接如下: HOME 和 JavaScript 函
我试图将对函数的引用作为参数传递 很难解释 我会写一些伪代码示例 (calling function) function(hello()); function(pass) { if this =
我在尝试调用我正在创建的 C# 项目中的函数时遇到以下错误: System.Runtime.InteropServices.COMException: Operation is not allowed
使用 ksh。尝试重用当前脚本而不修改它,基本上可以归结为如下内容: `expr 5 $1 $2` 如何将乘法命令 (*) 作为参数 $1 传递? 我首先尝试使用“*”,甚至是\*,但没有用。我尝试
我一直在研究“Play for Java”这本书,这本书非常棒。我对 Java 还是很陌生,但我一直在关注这些示例,我有点卡在第 3 章上了。可以在此处找到代码:Play for Java on Gi
我知道 Javascript 中的对象是通过引用复制/传递的。但是函数呢? 当我跳到一些令人困惑的地方时,我正在尝试这段代码。这是代码片段: x = function() { console.log(
我希望能够像这样传递参数: fn(a>=b) or fn(a!=b) 我在 DjangoORM 和 SQLAlchemy 中看到了这种行为,但我不知道如何实现它。 最佳答案 ORM 使用 specia
在我的 Angular 项目中,我最近将 rxjs 升级到版本 6。现在,来自 npm 的模块(在 node_modules 文件夹内)由于一些破坏性更改而失败(旧的进口不再有效)。我为我的代码调整了
这个问题在这里已经有了答案: The issue of * in Command line argument (6 个答案) 关闭 3 年前。 我正在编写一个关于反向波兰表示法的 C 程序,它通过命
$(document).ready(function() { function GetDeals() { alert($(this).attr("id")); } $('.filter
下面是一个例子: 复制代码 代码如下: use strict; #这里是两个数组 my @i =('1','2','3'); my @j =('a','b','c'); &n
我是一名优秀的程序员,十分优秀!