为啥我不用 * 声明 NSInteger
Posted
技术标签:
【中文标题】为啥我不用 * 声明 NSInteger【英文标题】:Why don't I declare NSInteger with a *为什么我不用 * 声明 NSInteger 【发布时间】:2010-11-04 02:01:18 【问题描述】:我正在 iTunes U 上的斯坦福大学 iPhone 课程中尝试我的手,我对指针有点困惑。在第一个作业中,我尝试做这样的事情
NSString *processName = [[NSProcessInfo processInfo] processName];
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
产生了一个错误,在盲目地修补之后,我发现是 NSInteger 行中的 * 导致了问题。
所以我显然不明白发生了什么。我将解释我认为它是如何工作的,也许有人会很好地指出这个缺陷。
与 Web 开发不同,我现在需要 比 Web 开发更担心内存。所以当我 创建一个变量,它被分配一个 某处的内存位(RAM I 认为)。而不是通过 变量,我传递一个指针 周围的那一点记忆。和 指针是通过添加前缀来声明的 带 * 的变量名。
假设我是对的,让我感到困惑的是为什么我不需要为 NSInteger 这样做?
【问题讨论】:
【参考方案1】:NSInteger
是原始类型,这意味着它可以本地存储在堆栈中。您不需要使用指针来访问它,但如果您愿意,您可以。行:
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
返回一个实际变量,而不是它的地址。要解决此问题,您需要删除 *
:
NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];
如果你真的想要,你可以有一个指向 NSInteger
的指针:
NSInteger *pointerToProcessID = &processID;
& 号是操作符的地址。它将指向NSInteger
的指针设置为等于内存中变量的地址,而不是指向变量中的整数。
【讨论】:
我怀疑这将是一个非常方便的提示。谢谢。 当我从 webdev 转向 iPhone 开发时,这对我来说是一个重大问题。另一个需要注意的是确保以 nil 终止 NSArray。 如果你双击 NSInteger 或其他你在 XCode 中感到困惑的类型,你可以得到它的定义,在这种情况下是: typedef int NSInteger;所以它毕竟是一个普通的旧 int。 这是无效的。 & 运算符需要一个左值,而方法调用是一个右值。 另请注意,此示例仅在您要在同一调用堆栈中使用 processID 指针时才有用。如果以后需要使用它,则需要使用 calloc 在堆上分配内存,然后将值存储到该内存中。像这样的东西: NSInteger *processID = calloc(1, sizeof(NSInteger)); *processID = [[NSProcessInfo processInfo] processIdentifier];【参考方案2】:您不使用*
声明NSInteger
的原因是因为它不是对象。 NSInteger 只是一个 int
或 long
:
#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
endif
如果在 32 位应用程序中使用,则为 32 位整数,如果在 64 位应用程序中构建,则为 64 位整数。
当然,您可以将NSInteger
作为指针传递,但大多数函数只是将参数作为NSInteger
而不是指向它的指针。
另一方面,对象只能作为指针传递给其他函数。这是因为对象具有为它们动态分配的内存,因此不能在堆栈上声明。因为int
或long
为它们分配了固定数量的内存,所以这不是问题。
【讨论】:
【参考方案3】:*
表示“指针”。对象变量持有一个指向对象的指针,所以它有一个*
; NSInteger 变量包含一个 NSInteger,而不是指向 NSInteger 的指针,因此它没有*
。将*
放在该变量上至少会给您一个警告,因为您将整数放入指针变量中。
【讨论】:
【参考方案4】:NSInteger 只是 int 的 typedef,AFAIK。
【讨论】:
可以,但并非无处不在。在 64 位 Mac OS X 系统上,NSInteger
定义为 long
。不难想象,有朝一日在运行 ios 的架构上可能会出现这种情况。【参考方案5】:
使用指针
NSInteger integer1 = 1;
NSLog(@"1. integer1:%ld &integer1:%p", integer1, &integer1);
//1. integer1:1 &integer1:0x7ffee59e8a98
NSInteger *integer2 = &integer1;
NSLog(@"2. integer2:%p &integer2:%p *integer2:%ld", integer2, &integer2, *integer2);
//2. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:1
*integer2 = 2;
NSLog(@"3. integer2:%p &integer2:%p *integer2:%ld \t integer1:%ld &integer1:%p", integer2, &integer2, *integer2, integer1, &integer1);
//3. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:2 integer1:2 &integer1:0x7ffee59e8a98
【讨论】:
以上是关于为啥我不用 * 声明 NSInteger的主要内容,如果未能解决你的问题,请参考以下文章