【问题标题】:NSInvocation setArgument issueNSInvocation setArgument 问题
【发布时间】:2012-11-28 09:34:50
【问题描述】:

我需要使用 NSInvocation 来动态调用一个方法。 这是我尝试过的:

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[messageRecord.senderController class] instanceMethodSignatureForSelector:messageRecord.receiverAction]];

[invocation setSelector:messageRecord.receiverAction];
[invocation setTarget: messageRecord.senderController];
[invocation setArgument: &(message.data) atIndex:2];
[invocation invoke];

需要提一下,messageRecord.senderController 是要调用哪个方法的对象,messageRecord.receiverAction 是赋予这段代码的选择器。此外,message.data 是类型为 (NSArray *) 的对象,并且已正确初始化。

这段代码给出以下编译时错误

Address of property expression requested

当我如下更改调用过程时,它按预期工作:

NSArray *dataArray = message.data;

[invocation setSelector:messageRecord.receiverAction];
[invocation setTarget: messageRecord.senderController];
[invocation setArgument: &dataArray atIndex:2];
[invocation invoke];

两者之间的唯一区别是:我创建了一个本地 NSArray 指针并将 message.data 分配给它。后来,给出了新创建的指针的地址,而不是message.data 本身。

为什么有效?到底有什么区别?

【问题讨论】:

    标签: objective-c pointers nsinvocation


    【解决方案1】:

    正如 Shimanski Ahem 所提到的,财产不是有地址的东西。属性只是一对 getter 和 setter 方法。就是这样。 getter 和 setter 方法可以由您提供,也可以由编译器基于某个实例变量合成。如果它们是你提供的,它们也可以基于一些实例变量,但是你需要做一些额外的逻辑;或者他们可以基于其他事物完全动态地生成价值。因此,在某处可能没有与该属性相对应的“实例变量”。

    如果 getter 和 setter 是合成的,并且您知道它们所基于的实例​​变量(您可以从 synthesize 声明中获得;如果 synthesize 没有明确指定一个,则它与属性名称相同;或者如果在最新版本的编译器中省略并隐式指定了综合,则为 _data(前面带有下划线)。这就是 Shimanski Artem 显示的内容。

    但是,退一步问一下,为什么你首先需要一个指向值的指针?什么目的?如果您使用指向原始值的指针或指向该值的副本的指针,会有所不同吗?了解setArgument: 方法的工作原理以及它为什么需要指针将帮助您回答其中的许多问题。 setArgument: 允许您使用您选择的值设置调用中的参数之一,因此它真正关心 。那么为什么不直接让你传递值呢?那么,它会是什么类型的呢?不同的类型在 C 中有不同的大小,所以这是不可能的。因此,它要求您提供一个指向该值的指针(适用于任何类型),然后从那里复制它。所以它只关心指向的 value,而不关心特定的地址。这就是为什么(如您所见),当您想将setArgument: 与不可寻址的东西(如属性、更复杂的表达式或Objective-C++ 中的this 等)一起使用时,您可以简单地分配它到一个临时变量并获取它的地址。

    【讨论】:

      【解决方案2】:

      您不能获取物业的地址。这是语言细节。你可以试试这个表格:

      [invocation setArgument: &(message->data) atIndex:2];
      

      【讨论】:

      • 给出另一个错误:在“消息 *”类型的对象上找到属性“数据”:您是要使用“。”访问它吗?运营商?
      • 也许你的班级成员是_data
      猜你喜欢
      • 2023-03-03
      • 2012-01-30
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多