2。iOS基础知识—回顾

iOS基础知识点总结

2018-05-17  本文已影响7人  打碟的DJ

1.理解Block的使用

image

1、Block为什么要用copy

a、block在创建的时候默认分配的内存是在栈上,而不是在堆上。这样的话其本身的作用域是属于创建时候的作用域,一旦在创建的作用域之外调用就会导致程序的崩溃。所以使用了copy将其拷贝到堆内存上。

b、block创建在栈上,而block的代码中可能会用到本地的一些变量,只有将其拷贝到堆上,才能用这些变量

2、Block为什么不用retain

retain这是增加了一次计数,block的内存还是在栈上,并没有存在堆上,存在栈上的block可能随时被系统回收。

3、为什么进入block中的对象引用计数需要自动加1

Block执行的是回调,因此block并不知道其中的对象obj创建后会在什么时候被释放,为了不在block使用obj之前,对象已经被释放,block就retain了obj一次

4、block和函数的关系

Block的使用很像函数指针,不过与函数最大的不同是Block可以访问函数以外、词法作用域以内的外部变量的值。

换句话说,Block不仅能实现函数的功能,还能携带函数的执行环境。

5、对于block的理解

block实际上是: 指向结构体的指针

编译器会将block的内部代码生成对应的函数

6、对于基本数据类型,进入到block中会被当做常量处理。在块外面声明的实例变量默认情况下,在块中只能使用,但是不能修改。如果想修改,需要在变量前面添加__block

//如果需要在block中对num进行修改,需要加上关键字__block

//(我们也可以用static关键字进行修饰)

int  num1 =10;

void(^block1)() = ^{

    NSLog(@"num1 is %d",num1);

};

num1 =20;

block1();//输出10

//改进:使用block,使进入到block块中的变量不被当做常量来使用

__blockint  num2 =10;

void(^block2)() = ^{

    NSLog(@"num2 is %d",num2);

};

num2 =20;

block2();//输出20

7、Block中self的循环引用

block默认创建在栈上,所以对要对其进行执行copy操作,将其拷贝到堆区,便于更好的操作对象。但是执行了copy操作之后,block中使用self,此对象会被retain一次(注意:block在堆区上时才会起到retain作用),会造成循环引用。

解决方法:

在MRC下,使用__block修饰

在ARC下,使用__unsafe_unretained\weak修饰

2、理解循环引用出现的三种情况

1、NSTimer

NSTimer对象timer作为一个对象A的属性,本意在A的dealloc中释放timer,但是timer没有停止就不会触发dealloc,然后就互相等待,造成循环引用。解决方法是显式的调用timer的关闭方法[timer invaluate],再释放A对象

2、Block

block代码块没有配合weak使用

3、Delegate

声明delegate时请用assign(MRC)或者weak(ARC)。

循环引用举例:

NSMutableArray *firstArray = [NSMutableArray array];

NSMutableArray *secondArray = [NSMutableArray array];

[firstArrayaddObject:@"1"];

[secondArrayaddObject:@"2"];

[firstArrayaddObject:secondArray];

[secondArrayaddObject:firstArray];

NSLog(@"%@",firstArray);

检测循环引用

Xcode -> Product -> Pofile -> Leaks

3、区分nil、Nil、NULL、NSNULL

1、nil

nil一般是指把一个对象置空,即完全是一个空对象,完全从内存中释放

2、Nil

Nil和nil基本没什么区别,可以用nil的地方也可以用Nil。但是nil和Nil唯一的区别在于,nil是置空一个对象,而Nil是置空一个类。

3、NULL

NULL源于c,表示一个空指针,即:int *p = NULL;

4、NSNULL

NSNULL是以“NS”开头的,明显是一个对象,继承于NSObject。它相当于一个空对象(类似容器,比如一瓶矿泉水,我们不想要里面的水,只想保留瓶子一样)。

4、区分MRC和ARC内存管理

iOS 5以后出现了ARC,即自动引用计数(Automatic Refrence Counting),减少了代码,省去了对象释放的麻烦。

ARC项目中加入MRC:

在target → build phrase → compbile source,点击mrc的文件,将其设置为 -fno-objc-arc

MRC项目中加入ARC:

在target → build phrase → compbile source,点击arc的文件,将其设置为 -fobjc-arc

iOS通过引用计数来记录对象的引用,每次runloop完成一次循环的时候,都会检测对象的retainCount,如果说对象的retainCount为0的话,说明该对象没有地方需要引用了,就可以释放掉了。

上一篇 下一篇

猜你喜欢

热点阅读