平常只顾撸码,导致忽视了知识点的总结,最近有些闲暇时间来整理整理一些知识点,供时不时的翻阅。如有侵权,请及时联系我。
1,什么情况下会出现循环引用?
循环引用是两个或者两个以上对象互相强引用,导致所有对象无法被释放的现象。这是内存泄漏的一种情况。
//---- class Father ---
@interface Father :NSObject
@property (nonatomic,strong)Son *son;
@end
//---- class Son ---
@interface Son :NSObject
@property (nonatomic,strong)Father *father;
@end
上述的代码有两个类,分别为Father和Son,Father对Son是强引用,Son对Father强引用。所以,要释放Son,则先释放Father,要释放Father则必须释放Son,如此一来,两个对象都无法被释放。
解决方法是将Father中的Son对象的属性由Strong改为Weak。
内存泄漏可以用Xcode中的Debug Memory Graph检查:
同时,Xcode也会在runtime中自动汇报内存泄漏的问题:
2,strong,weak,assign,和copy区别:
strong表示指向并拥有该对象。其修饰的对象引用计数会增加1.该对象只要引用计数不为0,就不会销毁。当然,强行将其设为nil也可以销毁它。
weak表示指向但不拥有该对象。其修饰的对象引用计数不会增加。无需手动设置,该对象会自行在内存中被销毁。
assign主要修饰基本的数据类型,如NSInteger和CGFloat,这些数值主要存于栈中。
weak一般用于修饰对象,assign一般用于修饰基本的数据类型。原因是assign修饰的对象被释放后,指针的地址依然存在,造成“野指针”,在堆上容易造成崩溃。而栈上的内存系统自动处理,不会造成“野指针”。
assign、weak不同点:
assign 可以用非 OC 对象,而 weak 必须用于 OC 对象。
weak 表明该属性定义了一种“非拥有关系”。在属性所指的对象销毁时,属性值会自动清空(nil)。
copy与strong类似。不同之处是,strong的复制是多个指针指向同一个地址,而copy的复制是每次会在内存中复制一份对象,指针指向不同地址。copy一般用在修饰有对应可变类型的不可变对象上,如NSString,NSArray,NSDictionary。
注:在Objection-C中,基本的数据类型默认的关键字是atomic,readwrite和assign;普通属性的默认关键字是atomic,readwrite和strong
3,atomic和nonatomic区别
atomic修饰的对象会保证setter和getter的完整性,任何线程访问它都可以得到一个完整的初始化对象。因为要保证操作完成。所以速度比较慢。atomic比nonatomic安全,但也不是绝对的线程安全,例如,当多个线程同时调用set和get时,就会导致获取的对象值不一样。要想线程绝对安全,就要用@synchronized。
nonatomic修饰的对象不保证setter和getter的完整性,所以,当多个线程访问它时,它可能会返回未初始化的对象。正因为如此,nonatomic比atomic的速度快,但是线程也是不安全的。
4,runloop和线程有什么关系
runloop是每一个线程一直运行的一个对象,它主要用来负责响应需要处理的各种事件和消息。每一个线程都有且仅有一个runloop与其对应,没有线程,就没有runloop。
在所有线程中,只有主线程的runloop是默认启动的,main函数会设置一个NSRunloop对象。而其他线程的runloop默认是没有启动的,可以通过 [NSRunLoop currentRunLoop]来启动。
5,__weak和__block区别
__weak与weak基本相同。前者用于修饰变量(variable),后者用于修饰属性(property)。
__weak主要用于防止block中的循环引用。
__block也用于修饰变量。它是引用修饰,所以,其修饰的值是动态变化的,既可以被重新赋值的。__block用于修饰某些block内部将要修改的外部变量。
__weak和__block的使用场景几乎与block息息相关。而所谓block,就是Objection-C对于闭包的实现。闭包就是没有名字的函数,或者可以理解为指向函数的指针。
6,请问下面的代码有什么问题(属性申明代码风格考查)
@property (nonatomic,strong) NSString *title;
@property (assign,nonatomic) int workID;
title不应该用strong来修饰,而应该用copy。因为NSString是不可变的数据类型,它有对应的NSMutableString数据类型,用strong来修饰会有NSString被修改的可能。
例子:
self.title = @"title";
NSMutableString *mutableTitle = @"mutableTitle";
self.title = mutableTitle;
原来title的值是“title”,后来被改成了“mutableTitle”。
有对应可变数据类型的不可变数据类型都应该修饰为copy。copy表示该属性不能被修改,如果对可变类型如NSMutableString用copy修饰,那么当对其进行修改时,程序就会崩溃。
workID不应该用int类型,而应该用NSInteger类型。int只表示32位的整形数据,而NSInteger在32位计算机中与int一样,