带有指针的Objective-C转换[duplicate]

时间:2022-01-04 21:43:46

This question already has an answer here:

这个问题已经有了答案:

I am new to Objective-C and come from a Java background. I have just gone over casting in Objective-C but the book I am using failed to explain the use of the '*'/pointer when casting. Here is the example they gave me:

我是Objective-C的新手,有Java背景。我刚刚在Objective-C中讨论了角色转换,但是我正在使用的书没有解释角色转换时使用的“*”/指针。这是他们给我的例子:

myFraction = (Fraction *) fraction;

Aren't pointers for specific objects so they have their own unique memory location? So then why must I use a pointer when simply referencing a class? In this case, Fraction.

指针不是针对特定对象的,所以它们有自己的唯一内存位置吗?那么,为什么在引用类时必须使用指针呢?在这种情况下,分数。

Thanks I hope this makes sense and I know this is a simple question that I should know and understand but I could find nothing explaining this.

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

4 个解决方案

#1


3  

The * symbol has multiple meanings (beside multiplication :):

*符号有多重含义(除乘法外:):

  1. Dereference (follow) pointers. This code follows pointer stored in pointerToInt and then assigns a value to it.

    废弃(遵循)指针。此代码遵循存储在pointerToInt中的指针,然后为其分配一个值。

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

    声明一个指针类型。当你写int *时,它的意思是“对一个整数的引用”。

    int x = 5;
    int * xPtr = &x
    

Now, objects are a kind of structures, but we only manipulate with them via pointers. Never directly. This basically means, that 99% of time when you see * (and it's not multiplication :) it is the second case: a part of type declaration:

对象是一种结构,但我们只通过指针来操作它们。从来没有直接。这基本上意味着,当你看到*(它不是乘法)的99%时,它是第二种情况:类型声明的一部分:

  • NSString * = pointer to NSString structure (you can't use NSString alone)
  • NSString * =指向NSString结构的指针(你不能单独使用NSString)
  • Fraction * = pointer to Fraction structure and Fraction structure is described in Fraction class
  • 分数* =分数结构和分数结构的指针

So it's not “pointer to the Fraction class”, but rather “pointer to structure of Fraction class”.

所以它不是“分数类的指针”,而是“分数类结构的指针”。


I will go a little further and answer your future question about two **. You may see this usually with NSError arguments that are defined like methodWithError:(NSError **)errorPtr.

我再深入一点,回答你关于两个**的问题。NSError参数的定义通常类似于methodWithError:(NSError *)errorPtr。

Short story: int is to int * as NSError * is to NSError **.

短篇故事:int是int *, NSError *是NSError *。

Long story: If we cannot manipulate with objects directly (without pointers to them), the single pointer becomes standard part of declaration. Now what if we want to make indirect access to the object? We use double pointer! First * is required for object, second is for indirection.

长话短说:如果我们不能直接操作对象(没有指向对象的指针),那么单个指针将成为声明的标准部分。如果我们想间接访问对象呢?我们使用双指针!第一个*是对象所需要的,第二个是间接的。

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.

I believe pointers are weird when you come from Java. They are a bit of legacy from C, but they are not used in any crazy way.

我相信当你来自Java的时候,指针是很奇怪的。它们是来自C的一些遗产,但它们并没有以任何疯狂的方式使用。

#2


2  

The * symbol is simply syntax that's used when referring to pointers.

符号是指指针时使用的简单语法。

Here, myFraction, and fraction are both variables that hold pointers (they aren't objects themselves – in fact you never have variables that hold Objective-C objects, objects must always be referred to with pointers).

在这里,myFraction和fraction都是包含指针的变量(它们不是对象本身——事实上,你从来没有包含Objective-C对象的变量,对象必须总是通过指针被引用)。

The (Fraction*) syntax describes a cast to a pointer-to-a-Fraction of the expression on its right (in this case the fraction variable).

语法(Fraction*)描述了对右边表达式(在本例中是Fraction变量)的指针-a-分数的转换。

#3


1  

Remember that a pointer is just a variable that holds a memory location.

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

In Objective-C, when you have an object, what you really have is a pointer to an object, that is, a variable whose value is the memory address where the object really is.

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

Casting a pointer to a pointer of another type has no effect at runtime (at least for objects). In fact all your objects could be of type (void *). The casting helps the compiler to know what kind of object the pointer is pointing to, and generate errors or warnings.

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

If these two little paragraphs don't make much sense to you right now, consider reading some basic information or tutorials on pointers. Understanding pointers can be challenging for a beginner or from someone transitioning form the Java world.

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

#4


1  

...failed to explain the use of the '*'/pointer when casting...

…未能解释在强制转换时使用“*”/指针。

Pointers have little to do with casting, other than being part of a type specifier. Consider:

指针除了作为类型说明符的一部分之外,与转换几乎没有关系。考虑:

  • Fraction is a type -- for the sake of argument, let's imagine that it's the name of a class, and that Fraction is a subclass of another class called Number.

    分数是一种类型——为了讨论,我们假设它是一个类的名字,这个分数是另一个叫做Number的类的子类。

  • Fraction * is a pointer to an instance of the Fraction class. In Objective-C, you always use pointers to refer to objects, so you'll see a lot of variables with types of the form ClassName *.

    分数*是分数类实例的指针。在Objective-C中,您总是使用指针来引用对象,因此您将看到许多具有类名类型的变量*。

Casting is simply a matter of telling the compiler that it should treat a variable as a certain type. So, let's say you've got a variable number of type Number * and you know that the object it points to is actually a Fraction. However, you can't use any of the methods that are specific to Fraction because, as far as the compiler is concerned, number is just a Number *. You can use a type cast to tell the compiler: "I know what I'm doing, and number is definitely pointing to an instance of Fraction, so please treat number as a Fraction *." You do it like this:

强制转换只是告诉编译器,它应该将变量视为某种类型。假设你有一个变量number类型*你知道它指向的对象实际上是一个分数。但是,您不能使用任何特定于分数的方法,因为就编译器而言,数字只是一个数字*。您可以使用类型转换来告诉编译器:“我知道我在做什么,number肯定指向一个分数实例,所以请将number当作分数*。”你这样做:

Fraction *f = (Fraction *)number;

But again, the * doesn't have any special significance in the casting operation beyond the fact that Fraction * is the type to which you're casting number.

但同样,除了分数*是你要铸造的数字类型之外,*在铸造操作中没有任何特殊的意义。

#1


3  

The * symbol has multiple meanings (beside multiplication :):

*符号有多重含义(除乘法外:):

  1. Dereference (follow) pointers. This code follows pointer stored in pointerToInt and then assigns a value to it.

    废弃(遵循)指针。此代码遵循存储在pointerToInt中的指针,然后为其分配一个值。

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

    声明一个指针类型。当你写int *时,它的意思是“对一个整数的引用”。

    int x = 5;
    int * xPtr = &x
    

Now, objects are a kind of structures, but we only manipulate with them via pointers. Never directly. This basically means, that 99% of time when you see * (and it's not multiplication :) it is the second case: a part of type declaration:

对象是一种结构,但我们只通过指针来操作它们。从来没有直接。这基本上意味着,当你看到*(它不是乘法)的99%时,它是第二种情况:类型声明的一部分:

  • NSString * = pointer to NSString structure (you can't use NSString alone)
  • NSString * =指向NSString结构的指针(你不能单独使用NSString)
  • Fraction * = pointer to Fraction structure and Fraction structure is described in Fraction class
  • 分数* =分数结构和分数结构的指针

So it's not “pointer to the Fraction class”, but rather “pointer to structure of Fraction class”.

所以它不是“分数类的指针”,而是“分数类结构的指针”。


I will go a little further and answer your future question about two **. You may see this usually with NSError arguments that are defined like methodWithError:(NSError **)errorPtr.

我再深入一点,回答你关于两个**的问题。NSError参数的定义通常类似于methodWithError:(NSError *)errorPtr。

Short story: int is to int * as NSError * is to NSError **.

短篇故事:int是int *, NSError *是NSError *。

Long story: If we cannot manipulate with objects directly (without pointers to them), the single pointer becomes standard part of declaration. Now what if we want to make indirect access to the object? We use double pointer! First * is required for object, second is for indirection.

长话短说:如果我们不能直接操作对象(没有指向对象的指针),那么单个指针将成为声明的标准部分。如果我们想间接访问对象呢?我们使用双指针!第一个*是对象所需要的,第二个是间接的。

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.

I believe pointers are weird when you come from Java. They are a bit of legacy from C, but they are not used in any crazy way.

我相信当你来自Java的时候,指针是很奇怪的。它们是来自C的一些遗产,但它们并没有以任何疯狂的方式使用。

#2


2  

The * symbol is simply syntax that's used when referring to pointers.

符号是指指针时使用的简单语法。

Here, myFraction, and fraction are both variables that hold pointers (they aren't objects themselves – in fact you never have variables that hold Objective-C objects, objects must always be referred to with pointers).

在这里,myFraction和fraction都是包含指针的变量(它们不是对象本身——事实上,你从来没有包含Objective-C对象的变量,对象必须总是通过指针被引用)。

The (Fraction*) syntax describes a cast to a pointer-to-a-Fraction of the expression on its right (in this case the fraction variable).

语法(Fraction*)描述了对右边表达式(在本例中是Fraction变量)的指针-a-分数的转换。

#3


1  

Remember that a pointer is just a variable that holds a memory location.

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

In Objective-C, when you have an object, what you really have is a pointer to an object, that is, a variable whose value is the memory address where the object really is.

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

Casting a pointer to a pointer of another type has no effect at runtime (at least for objects). In fact all your objects could be of type (void *). The casting helps the compiler to know what kind of object the pointer is pointing to, and generate errors or warnings.

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

If these two little paragraphs don't make much sense to you right now, consider reading some basic information or tutorials on pointers. Understanding pointers can be challenging for a beginner or from someone transitioning form the Java world.

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

#4


1  

...failed to explain the use of the '*'/pointer when casting...

…未能解释在强制转换时使用“*”/指针。

Pointers have little to do with casting, other than being part of a type specifier. Consider:

指针除了作为类型说明符的一部分之外,与转换几乎没有关系。考虑:

  • Fraction is a type -- for the sake of argument, let's imagine that it's the name of a class, and that Fraction is a subclass of another class called Number.

    分数是一种类型——为了讨论,我们假设它是一个类的名字,这个分数是另一个叫做Number的类的子类。

  • Fraction * is a pointer to an instance of the Fraction class. In Objective-C, you always use pointers to refer to objects, so you'll see a lot of variables with types of the form ClassName *.

    分数*是分数类实例的指针。在Objective-C中,您总是使用指针来引用对象,因此您将看到许多具有类名类型的变量*。

Casting is simply a matter of telling the compiler that it should treat a variable as a certain type. So, let's say you've got a variable number of type Number * and you know that the object it points to is actually a Fraction. However, you can't use any of the methods that are specific to Fraction because, as far as the compiler is concerned, number is just a Number *. You can use a type cast to tell the compiler: "I know what I'm doing, and number is definitely pointing to an instance of Fraction, so please treat number as a Fraction *." You do it like this:

强制转换只是告诉编译器,它应该将变量视为某种类型。假设你有一个变量number类型*你知道它指向的对象实际上是一个分数。但是,您不能使用任何特定于分数的方法,因为就编译器而言,数字只是一个数字*。您可以使用类型转换来告诉编译器:“我知道我在做什么,number肯定指向一个分数实例,所以请将number当作分数*。”你这样做:

Fraction *f = (Fraction *)number;

But again, the * doesn't have any special significance in the casting operation beyond the fact that Fraction * is the type to which you're casting number.

但同样,除了分数*是你要铸造的数字类型之外,*在铸造操作中没有任何特殊的意义。