抛转引玉
我们在创建UITableViewCell的时候,经常编写这样的代码。
static NSString *ID = @"XXXcell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
这段代码在cell复用机制时,ID变量前面是用static修饰的。为什么?
我们首先了解一下static关键字用来修饰局部变量的例子:
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self test];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"---------- viewWillAppear -------------");
[self test];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"---------- viewDidAppear -------------");
[self test];
}
- (void)test {
NSInteger i = 0;
i++;
static NSInteger staticValue = 0;
staticValue++;
NSLog(@"i = %ld, s.value = %ld", (long)i, (long)staticValue);
}
三次打印结果如下:
2019-03-26 23:07:31.701825+0800 111[1565:93233] i = 1, s.value = 1
2019-03-26 23:07:31.702135+0800 111[1565:93233] ---------- viewWillAppear -------------
2019-03-26 23:07:31.702259+0800 111[1565:93233] i = 1, s.value = 2
2019-03-26 23:07:31.773928+0800 111[1565:93233] ---------- viewDidAppear -------------
2019-03-26 23:07:31.774978+0800 111[1565:93233] i = 1, s.value = 3
可以看到,对于局部变量(它是一个普通变量)i,每次程序执行test方法的时候,它的值都是从0开始,然后自增1,反观被static修饰的变量staticValue,每次程序执行test的时候,它的值总是在原来的值基础上自增1。也即是说经过static修饰的变量在整个应用程序开始到结束这段时间内存没变化(没有被销毁),每次程序执行到它的位置时,它的值总是从原来的值改变后得到新的值。对于普通的局部变量,我们知道在内存当中他们是分配到栈上的,栈上的变量出了函数体也就是大括号后会自动销毁。
现在我们可以解释一下文字开头的问题。
为了防止cell复用的时候频繁创建局部变量ID,我们在ID前面加了static关键字,程序编译的时候发现是static关键字,则只会在内存中创建一份,而且它的值就是常量字符串:“XXXcell”。
延伸:对于频繁调用的方法,我们在其内部定义变量前加static关键字可以达到只创建一次内存多次使用的好处。