Objective-C指针类型转换

3

我是Objective-C的新手,来自Java背景。我刚刚学习了Objective-C中的类型转换,但是我使用的书籍没有解释在类型转换时使用'*'指针符号的原因。这是他们给我的例子:

myFraction = (Fraction *) fraction;

指针不是针对特定对象的吗,所以它们有自己独特的内存位置?那么当我只是引用一个类(Fraction)时,为什么必须使用指针呢?

谢谢,希望这有意义,我知道这是一个简单的问题,我应该知道和理解,但我找不到任何解释。


3
请在尝试学习Objective-C之前,务必学习C或C++。您需要理解指针的工作原理,而Objective-C并不是学习这方面知识的好平台。 - Hot Licks
1
“为什么我们创建的对象都是指针?”这个问题也很好。 - jscs
我认为这个问题不是“Objective-C和指针”的重复——那个问题的答案很差(被接受的答案只是一些链接)。对于刚接触Objective-C的人来说,“对象”实际上总是“指向对象的指针”,这是一个合理的困惑点。 - James
@James - 对于那些有C或C++基础的人来说,这不应该是一个困惑点,而且对于开始编写Objective-C程序来说,基本的熟悉也是必要的。 - Hot Licks
@Josh Caswell,我明白为什么我们需要指针来处理对象,但是对于类的引用却不需要。 - jer_francis
你的问题中没有引用一个类。你是在告诉编译器一个对象的类型。 - jscs
4个回答

3
*符号有多重含义(除了乘法之外):
  1. Dereference (follow) pointers. This code follows pointer stored in pointerToInt and then assigns a value to it.

    (*pointerToInt) = 5;
    
  2. Declares a pointer type. When you write int * it means “reference to an integer”.

    int x = 5;
    int * xPtr = &x
    
现在,对象是一种结构,但我们只能通过指针来操作它们。从不直接操作。这基本上意味着,当您看到 * 时(而且它不是乘法 :))99% 的时间都是第二种情况:类型声明的一部分:
  • NSString * = 指向 NSString 结构的指针(无法使用单独的 NSString
  • Fraction * = 指向 Fraction 结构的指针,且 Fraction 结构在 Fraction 类中描述
因此,它不是“指向 Fraction 类的指针”,而是“指向 Fraction 类结构的指针”。
我将进一步回答您未来有关两个 ** 的问题。您通常会在定义为 methodWithError:(NSError **)errorPtrNSError 参数中看到此问题。
简而言之:intint *NSError *NSError **
长话短说:如果我们不能直接操作对象(没有对它们的指针),那么单个指针将成为声明的标准部分。现在,如果我们想要对对象进行间接访问怎么办?我们使用双重指针!第一个 * 是对象所需的,第二个是指向它的间接引用。
NSError *error = nil; // Empty.
NSError **errorPtr = &error; // Reference to our local `error` variable.

[data writeToURL:URL options:kNilOptions error:errorPtr];
// That method uses:   (*errorPtr) = [NSError errorWith...];

NSLog(@"Error: %@", error); // Our local error is no longer empty.

我相信对于从Java转过来的人来说,指针很奇怪。它们是从C语言中遗留下来的一种机制,但并没有被用在什么疯狂的方式。


2
*符号在IT技术中通常用于指针的引用。
在这里,myFractionfraction都是存储指针的变量(它们本身不是对象 - 实际上,您从来没有存储Objective-C对象的变量,对象必须始终使用指针引用)。 (Fraction*)语法描述了对其右侧表达式(在此处为fraction变量)的指向Fraction的指针的强制转换。

1
“……未能解释在转换时使用‘*’/指针的用途……”
指针与转换关系不大,除了它是类型说明符的一部分。例如:
- “Fraction”是一个类型——为了举例,我们假设它是一个类的名称,并且“Fraction”是另一个名为“Number”的类的子类。 - “Fraction *”是指向“Fraction”类实例的指针。在Objective-C中,您总是使用指针来引用对象,因此您会看到许多类型形如“ClassName *”的变量。
转换类型只是告诉编译器应将变量视为某种类型的简单操作。假设您有一个类型为Number *的变量number,并且您知道它所指向的对象实际上是一个Fraction。但是,您不能使用任何特定于Fraction的方法,因为就编译器而言,number只是一个Number *。您可以使用类型转换来告诉编译器:“我知道自己在做什么,并且number肯定指向Fraction的实例,请将number视为Fraction *。”您可以像这样执行它:
Fraction *f = (Fraction *)number;

但是,* 在转换操作中并没有任何特殊意义,除了 Fraction * 是你要将 number 转换成的类型之外。


1

记住,指针只是一个保存内存位置的变量。

在Objective-C中,当你有一个对象时,你实际上拥有的是一个指向对象的指针,也就是一个值为对象真正所在内存地址的变量

将指针转换为另一种类型的指针在运行时没有任何影响(至少对于对象而言)。事实上,你所有的对象都可以是(void *)类型。转换帮助编译器知道指针指向的对象类型,并生成错误或警告。

如果这两个小段落现在对你来说没有太多意义,请考虑阅读一些有关指针的基本信息或教程。理解指针对于初学者或从Java世界过渡的人来说可能是具有挑战性的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接