一、 property
有哪些属性修饰词?
atomic nonatomic strong weak copy assign readwrite readonly
getter setter unsafe_unretained nononull nullable null_resetable
写在后面:
Q:ARC下property
的默认关键字是?
A:@property()CGFloat marginLeft;
// 修饰基本数据类型默认的关键字是atomic
,readwrite
,assign
。
@property()NSObject *obj;
// 修饰普通OC对象默认的关键字是atomic
,readwrite
,strong
。
二、 weak
和assign
的区别
· weak
只可以修饰对象。如果修饰基本数据类型,编译器会报错 - “property with ‘weak’ attribute must be of object type”。
weak
适用于delegate和block等引用类型,还有自定义IBOutlet控件也使用weak
修饰,不会导致野指针问题,也不会循环引用,非常安全。
· assign
可修饰基本数据类型,也可修饰对象。但是当修饰对象类型时,MRC时代使用unsafe_unretained
修饰。ARC下使用assign
修饰对象也可看作是unsafe_unretained
,这就可能会产生野指针。
Q:`weak`不会造成野指针问题的原因:
A:`weak` 不会产生野指针问题,因为weak修饰的对象释放后(引用计数器值为0),指针会自动被置nil,之后再向该对象发消息也不会崩溃。 weak是安全的。
Q:`assign`可能会造成野指针问题的原因:
A:`assign` 如果修饰对象,会产生野指针问题;如果修饰基本数据类型则是安全的。修饰的对象释放后,指针不会自动被置空,此时向对象发消息会崩溃。
写在后面:
Q:weak
修饰的对象释放后,指针被置为nil
的过程?
A:runtime
对注册的类,会进行布局,对于weak
对象会放入一个hash表中,用weak
指向的对象的内存地址作为key,当次对象的引用计数为0时会dealloc
,假如weak指向的对象的内存地址是a,那么就会以a为键,在这个hash表中搜索,找到所有以a为键的weak
对象,从而置为nil
。
三、strong
和weak
的区别
·weak
是弱引用,strong
是强引用,strong
修饰的属性一般不会自动释放;
· 在OC实际开发中属性对象一般用strong
来修饰,在使用懒加载定义控件的时候,一般也用strong。
·在使用 sb
或者 xib
给控件拖线的时候,拖出来的属性都是用 weak 修饰的
写在后面:
Q:使用sb
或者xib
给控件拖线的时候,拖出来的属性都是用 weak 修饰的 ?
@property (weak, nonatomic) IBOutlet UILabel *label;
A:在向xib
或者sb
里面添加控件的时候,添加的子视图是添加到了根视图View上面, 而控制器对其根视图 View默认是强引用的,当我们的子控件添加到View上面的时候,[self.view addSubView: self.mainView] ;
这个方法会对添加的控件进行强引用,如果在用strong
对添加的子控件进行修饰的话,相当于有两条强指针对子控件进行强引用, 为了避免这种情况,所以用weak
修饰.
四、什么情况下使用copy
关键字?
- 修饰
NSString
,NSArray
,NSDictionary
,NSNumber
,NSString
等经常使用copy
关键字:
因为他们有相应的可变类型。
- 注意:
NSMutableArray
,NSMutableDictionary
,NSMutableString
等经常使用strong
关键字 - 理由:
--NSArray
类型使用copy
修饰,防止值和类型被意外修改; 使用strong
修饰时,值和类型可能会被修改;
--NSMutableArray
使用strong
修饰,因为如果使用copy
修饰的话,创建的是不可变对象,再对不可变对象执行增删改操作就会crash
.
-
block
也经常使用copy
关键字:
block
使用copy
是从MRC上遗留下来的传统,在MRC中,方法内部的block
是放在栈区的,使用copy
可以把它放在堆区;在ARC中,使用copy
和weak
都可以。
写在后面:
Q:block
有什么类型,都存放在那里?
A:block
一共有3种类型。
1._NSConcreateGloubalBlock
,全局的静态block
,类似函数,如果block
里面不获取任何外部变量,或者变量是全局作用域时,如成员变量属性,那么就是global类型。
2._NSConcreateStackBlock
,保存在栈中的block
,栈都是由系统管理内存,当函数返回时会被销毁,__block
类型的变量也会被销毁,为了不被销毁。block会将block
和__block
变量从栈拷贝到堆。
3.__NSConcreateMallocBlock
,保存在堆中的block
,堆内存由开发人员控制,当引用计数为0时被销毁。
网友评论