【问题标题】:Objective C Types as parameterObjective C 类型作为参数
【发布时间】:2013-06-13 17:49:11
【问题描述】:

好的,我不是在问如何在调用方法或其他东西时获取参数。

我想要这样的东西:

-(void)doSomethingWithType:(TYPE)type {

//do something

}

并像这样执行:

[self doSomethingWithType:int];

[self doSomethingWithType:BOOL];

如何为具有类型作为参数的方法/函数创建参数?我的意思是任何类型.. :)

我不想做一个 int 参数,我想做一个 int 类型的参数,你将目标 c 类型写为参数而不是值或变量:)

谢谢!

【问题讨论】:

  • 我怀疑这对于非类类型是可能的。 Objective-C 是 C,像 int 这样的类型没有任何运行时表示。
  • 类型只是编译器(解析器?)遵循和理解代码的概念。与在 Objective-C 中实际上是对象的类不同,我怀疑原生变量类型在编译器之外有任何意义。
  • 提供更多关于您尝试使用该类型做什么的详细信息可能会有所帮助,以便人们可以就您如何完成该任务提出替代建议。

标签: objective-c


【解决方案1】:

我不确定我是否正确理解了你的意图,但 Objective-C 有一个类“Class”。

-(void)doSomethingWithType:(Class)type {
    //do something
    //for example, create an instance of this type:
    id object = [[type alloc] init];
}

你可以这样称呼它:

[objectOfMyClass doSomethingWithType: [SomeObjectiveCType class]];

但它不适用于原始类型。我的意思是 BOOL、int、float 等。仅限 Objective-C 类。 希望,它会有所帮助。抱歉,如果这不是您要查找的内容。

【讨论】:

  • 我已经尝试过这种方法,这就像一个魅力! :) 谢谢@FreeNickname! 但是内存问题呢?是否有任何特殊考虑需要考虑传递类类型?我问它是因为 xCode 提示使用 __unsafe_unretained Class
  • @KiNG,很高兴能帮上忙 :) 至于您的问题,请查看this question。那里有一个小对话。它甚至还有一个link to the documentation :) 重写它对于评论来说有点太长了,但很快:没什么好担心的:)
  • 感谢@FreeNickname :) 我是一名 C# 和以前的 Delphi 开发人员,老实说,我对 Objective-C 中的内存管理系统以及所有弱和强的东西仍然不满意! :p
  • @KiNG,也谢谢你 :) 直到你问我才知道这件事 :) 我不知道你是否读过这篇文章,但是这篇论文很好地描述了手动内存管理: Advaned memory management programming guide。我认为了解基础知识是件好事,尽管现在 ARC 统治着这片土地。顺便说一句,Transitioning to ARC.
  • @KiNG,这些手册相当简短,解释了内存管理的原则和约定。关于CoreFoundation,有another paper。但我不知道它是否是最新的。我还没有使用 ARC 与 CoreFoundation 合作过。
【解决方案2】:

类型不是 C 或 Objective-C 中的 first-class,因此您不能将它们传递给函数。

Objective-C 代码通常将它们表示为 char *@encode 之类的东西。所以,例如:

- (void)doSomethingWithType:(char *)encodedType {
    NSLog(@"Got type %s", encodedType);
}

[self doSomethingWithType:@encode(int)];

您可以在Apple Docs 中看到@encode 的作用。

另一种方法是使用宏(而不是方法),它可以将任意源文本作为参数来创建新代码。例如:

#define MY_MACRO(SYMBOL, TYPE) DoSomething(#SYMBOL, (TYPE *)&SYMBOL)

您会使用如下:

MY_MACRO(foo, int);

相当于代码:

DoSomething("foo", (int *)&foo);

宏中 SYMBOL 前面的“#”表示“用这个创建一个字符串”。请注意,在编写宏时会有很多的陷阱;我强烈建议您先在谷歌上搜索一下它们的良好入门。

【讨论】:

  • 是的,如果您查看我在最后链接的文档,您会发现"i" 对应于int。你只想要类型的 name 作为字符串吗?
  • 我要使用类型。就像我有这样的代码:MSHookFunction(((TYPE*​​)MSFindSymbol(NULL, "SYMBOL")),(TYPE*​​)$ SYMBOL,(TYPE*​​)&old__SYMBOL);如果我对多个符号和类型执行此操作,则会出现大量代码重复,因此我想要一个将 TYPE 作为参数的函数以在代码中使用它。所以我不必检查类型,只需在函数中使用一次代码,然后调用函数,如 startSomething(int, "SYMBOL");
  • @xCoder 我添加了另一个建议。
【解决方案3】:
  1. Apple 框架通常使用@encode。苹果定义的格式甚至可以描述原始类型的数组。优点 - 相当标准。缺点 - 您必须在调用方法之前添加编码类型的代码并将解码添加到您的方法中。

  2. 为您需要的每种类型提供单独的方法。缺点 - 很多方法。优点 - 易于阅读的代码,易于使用的代码。

  3. 宏而不是方法。宏可以采用任何参数,包括类型名称。缺点 - 代码难读,优点 - 代码短,易于使用。

但是,没有一个解决方案是完美的。如果你需要这样的东西,在大多数情况下它只是由一个非常糟糕的设计引起的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多