关于ios:创建类的实例返回警告?

Creating an Instance of a Class Returns Warning?

我正在学习Objective-C中的课程。我创建了一个名为"currencyconverter"的课程。

据我所知,有多种方法可以在另一个文件中创建此类的实例。因此,在我的appdelegate.h中,我使用变量类型"id"创建了一个实例,如下所示:

1
2
3
4
5
6
@interface AppDelegate : UIResponder <UIApplicationDelegate>
{

id currencyConverter;

}

所以在我的appdelegate.m中,我可以这样声明它而不需要任何警告:

1
2
3
4
5
6
7
8
9
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Override point for customization after application launch.

currencyConverter = [[CurrencyConverter alloc] init];

return YES;

}

但是,当我像下面这样创建类的一个实例时,会收到一条警告:"unused variable:mycc"

1
2
3
4
5
6
7
8
9
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Override point for customization after application launch.

CurrencyConverter *myCC = [[CurrencyConverter alloc] init];

return YES;

}

注意,我没有在appdelegate.h中创建"mycc"的实例,我只为"currencyconverter"创建了这个实例。还要注意我做了

1
#import"CurrencyConverter.h"

在我的AppDelegate.m的顶部

所以我的问题是,为什么一种创建类实例的方法没有警告,而另一种方法没有警告?它们在技术上不是都没用过吗?…


1
2
CurrencyConverter *myCC = [[CurrencyConverter alloc] init];
return YES;

上面的变量myCC是一个局部变量。它的寿命只和这种方法一样长。但是该方法在下一行结束,不再提到myCC,因此创建它是毫无意义的;它开始存在并再次消失(这个货币转换器也是如此)。

(在另一个代码中,myCC是一个实例变量,因此它的值(一个不同的currencyconverter)在创建并分配给它之后仍然存在。在任何情况下,Objective-C编译器都不会抱怨未使用的实例变量,因为这个概念没有任何意义。)


您需要了解堆栈和堆,以及局部变量与实例变量的关系。

当您调用一个方法时,在它的""和""括号之间声明的变量是局部变量。它们只存在于方法的生命中。这些变量在"堆栈"上声明。

把这堆纸想象成一堆便笺纸。当您调用一个方法时,处理器会在堆栈上放置一张新的空白纸,并使用该纸存储方法中的所有局部变量。当您到达右大括号("")时,该方法返回,处理器将该方法的纸张从堆栈中取出并扔掉。那张纸上的任何信息都丢失了。

实际上,每当您使用左大括号时,编译器就会弹出一张新的空白纸,并且您声明的任何变量都会添加到新的空白纸中。当您到达匹配的右大括号时,将丢弃顶部的纸张,并丢弃在最内部的左大括号和右大括号之间声明的任何变量。一组大括号定义了一个"局部作用域"。这些大括号内声明的任何变量仅在大括号内可见,并且仅存在于大括号内。一旦程序退出右大括号,在左大括号和右大括号之间定义的所有变量都将被丢弃。

堆栈是这样的,但是计算机内存。这堆东西更像是一堆空的储藏室。当电脑第一次启动时,所有的柜子都是空的。有一个"堆栈指针"指向堆栈顶部的第一个空的cubby(内存位置)。如果将某个东西推到堆栈上,它将被存储到空的cubby中,堆栈指针将被移到下一个空的cubby中。如果您从堆栈中弹出一些内容,它将从堆栈顶部的第一个非空的cubby中取出,堆栈指针将向下指向现在为空的cubby。当您从一个方法返回或退出一组大括号时,编译器会记住您使用了多少堆栈空间,并从堆栈中弹出存储的所有内容并将其丢弃。

实例变量不同。它们存储在堆中,堆是一个内存块,在程序的生命周期中一直保存着。当您创建一个对象时,处理器从堆中为您的对象切出一块足够大的内存,并给您一个指向该内存的指针。然后初始化对象,将内存设置为"干净"的启动状态。如果释放一个对象,那么堆内存的那一部分就会被释放。堆中的存储空间不是从上到下的。更像是先到先得。如果创建10个对象,然后释放其中的4个对象,那么栈内存中就会有这些4个对象以前所在的孔。堆的空间更像是餐馆里的桌子。如果您请求一块内存,操作系统会在堆中寻找一块足够大(或大于)您所需大小的空闲内存,就像一个餐馆在最小的桌子上坐着一群人,这些人的桌子足够大,可以容纳整个组,即使桌子比组稍大。