为什么performSelector:withObject:方法只能使用id?

问题描述:

在Objective-C,进行选择的方法都一样:为什么performSelector:withObject:方法只能使用id?

- performSelector:withObject: 
- makeObjectsPerformSelector:withObject: 
- performSelectorInBackground:withObject: 

,只能采取ID(指针)对象的参数?你知道为什么吗 ?是从C继承的东西,并使用线程我们需要一个指针?


编辑:,以及我们不能直接创建指针的Objective-C。如果我想用指针做下面的事情,这是否正常工作? (我了解的NSNumber和NSValue类,但我只是想了解它是如何工作)

int i = 5; 
int *pointer_i = &i; 
[self performSelector:mySelector withObject:pointer_i]; 
+0

啊!你可以说它需要一个类型为void *的参数。但我仍然在这里理解你的问题。 – 2011-03-21 13:48:32

+1

@Praveen S每个'id'都是一个指针,但不是每个'void *'都是'id'。 – Jilouc 2011-03-21 14:09:07

你可以施放withObject:(id)pointer_i但这是一个坏主意
在这个特定的实例中,参数withObject:retain ed。如果您传入int *,而该方法预计为id,则您的程序会因为尝试retainint而崩溃!

+0

好的,谢谢!我刚才看到,如果我用我的int创建一个NSNumber,并且在我的函数中我尝试显示它,它显示一个奇怪的数字。 NSLog(@“我的号码:%i”,i);打印:1073752700这是指针地址? – 2011-03-22 14:27:35

+1

您正在使用格式说明符'%i'作为'int'。您应该切换到使用'%@'对象描述说明符或使用'[i intValue]'。 – Richard 2011-03-22 21:22:11

因为ID是一个指向任何类型的对象。所以你不需要知道你得到了什么类型的对象(NSString,NSArray)。一个id可以指向任何东西。

+0

所以,我假设我用int指针编辑工作? Xcode说“不兼容的指针类型'int *'到参数'id'”。我们知道'id'是'void *',所以我可以将我的指针放在'id'中并且它会起作用吗? – 2011-03-21 14:55:03

+1

将任意指针(如int *)传递给期望对象指针的接口要求麻烦,即使它现在看起来“工作”,这是不正确的,并可能很容易在后续的操作系统版本中破坏 – 2011-03-21 15:25:37

+0

我想换个说法,“id”是指向NSObject的任何子类的指针,而不是“指向任何类型对象的指针”,你绝对不能把'id'想象成void *。你不能做什么OP试图做和传递'INT *'(当然,你可以避开它,做它,但它是不聪明的话) – filipe 2011-03-22 14:16:32

你只能给指针作为参数,所以objective-c对象。如果你想使用一个整数,试试这个:

int i; 
[self performSelector:@selector(mySelector:) withObject:[NSNumber numberWithInt:i]]; 
+0

是的,我知道,(我更新了我的问题有关指针目标-C)。 – 2011-03-21 14:18:08

+0

那么问题还有哪些呢?只需使用NSNumber而不是直接int。 int是一个原始的,并且不使用的指针,而NSNumber的是它可以包含任何类型的原始数量的对象,并且是一个指针。 – 2011-03-21 14:19:52

+0

但是在C中,我们可以有一个指向int的指针。 – 2011-03-21 14:44:19

基本上你可以传入任何单个对象(如果你需要这种灵活性,它本身可以是一个数组或字典,当然你需要能够将它传递给你所调用的函数)

我离开这个答案的原因就是提到一个陷阱,使用这个时候会让我失望几个小时,如果在选择器名称后面留下冒号,应用程序将会编译,但是会在运行时崩溃时间。

要使用前面的例子

[self performSelector:@selector(mySelector:) withObject:[NSNumber numberWithInt:i]]; 

“mySelector:”需要冒号。

好的,也许这是一件小事,对硬核编码者来说很明显,但花了我很多时间去调试。如果你的代码崩溃了,并且你传递的对象是有效的,那么选择器可能不是。