我想对于ios开发的人来讲这3个关键字一定都很熟悉,但是你真的都明白了吗?下面模拟一下面试。我们一层层的深入分析。
1.请你说一下const和宏的区别
首先,很多字符串我们都定义成宏,但是苹果推荐的是使用const。
区别:
1.编译时刻:const是编译阶段,define是预编译阶段
2.编译检查:由于宏是预编译阶段处理,宏不做检查,只是单纯的替换。 const是会编译检查, 可以报编译错误。
3.宏的优势:可以定义函数,方法。const不行
4.宏的劣势:大量宏,会造成编译时间久,每次都需要重新替换。
好了,记下来会继续深入问你const
2.那你看这段代码给我说一下两种写法哪个会有问题
答案是两种写法都是对的。都是定义一个常量b,如果对b修改会引起报错;
下面继续:
int a = 10;
int *const p = &a;
int const *p = &a;
*p = 20;
p = &b;
说一下这两种写法有什么区别:
如果const修饰的是p,那么p的值是不能改变的,也就是p中存放的a的地址无法改变(p是int类型的指针变量)。但是*p是可以变化的,我们并没有
用const去修饰*p,所以可以通过*p去改变a的值
如果const修饰的是*p,那么*p的值是不能改变也,也就是p中存放的a的地址中的值无法改变,但是p的值是可以改变的(也就是p此时可以改变指向)
3.那你跟我说下static吧,static是做什么用的。
static就是修饰变量的,可以延长局部变量的生命周期,从栈区拿到全局区。恭喜你,这样答分数很低。面试官会给你几个demo。看看你是否真的理解了static。其实static的作用是需要细分的。
修饰局部变量:
1.延长局部变量的生命周期,程序结束才会销毁。
2.局部变量只会生成一份内存,只会初始化一次。
3.改变局部变量的作用域。
修饰全局变量
1.只能在本文件中访问,修改全局变量的作用域,生命周期不会改
2.避免重复定义全局变量
为了考察你的理解:会问你,那你说一下static在内存上怎么处理的。比如我现在有一个类,类中用static定义一个局部变量,每次执行这个static内存做了哪些事(从内存空间的角度)
-(void)method3:(NSMutableString *)str
{
static int n = 1;
// static等价语句
// if (变量n没有存储空间)
// {
// 给n分配存储空间
// }
[str appendFormat:@"%d ", n];
n++;
g1 = 400;
}
答:如同注释,将Int n 从栈区拿到全局区,延长n的生命周期到程序结束。如果多次调用method3方法。都会判断是否已经初始化了n,如果没有初始化,开辟内存空间,如果已经分配了,就把全局区的n,拿过来继续使用。
应该怎么理解呢。我们来看一下代码:
// static修饰全局变量
static int age = 10;
- (void)test
{
// static修饰局部变量
static int age = 0;
age++;
NSLog(@"%d",age);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self test];
[self test];
extern int age;
NSLog(@"%d",age);
}
如果你回答很含糊,很简单,面试官就会让你看一段伪代码,来考察一下你是不是真的懂了。首先输出结果是 1 , 2 ,10。这就考察了你是否真的理解static,首先,test里面试局部变量age。static的修饰只是延长了局部变量的生命周期。从栈区拿到了全局区。所以第一次输出1,第二次输出2,每次+1。最后一个行输出考察了extern,其实就是获取本文件的全局变量,后面我们会细说。所以这里全局变量定义了10,就输出10,而没有输出局部变量2.
好了,继续深入问:
.m中
const NSString *HSCoder = @"hello word";
另一个类的.m中
extern NSString *HSCoder;
NSLog(@"%@",HSCoder);
问你可以输出吗?hello word吗?
.m中
NSString *const nameKey = @"name"
.h中
extern NSString * const nameKey;
另一个类的.m中
NSLog(@"%@",nameKey);
问你可以输出name吗?
答案是都可以。这就是extern的用法
extern作用
:
extern工作原理
:
好了,继续问。如果将全局常量,加上static修饰,上面的代码会输出什么
static const NSString *HSCoder = @"hello word";
这里又考到了static的作用,千万不要想成什么延长生命周期,继续累加等等。。。注意到static的作用分为两方面。这里问的是修饰全局的。不改变生命周期,单纯的修改作用域。让这个常量只能在当前.m使用。所以,这段代码编译会报错