ios5之前是MRC,内存需要程序员进行管理,ios5之后是ARC,除非特殊情况,比如C框架或者循环引用,其他时候是不需要程序员手动管理内存的。
ios中当我们定义属性@property的时候就需要属性修饰符,下面我们就看一下不同属性修饰符的作用。有错误和不足的地方还请大家谅解并批评指正。
主要的属性修饰符有下面几种:
- copy
- assign
- retain
- strong
- weak
- readwrite/readonly (读写策略、访问权限)
- nonatomic/atomic (安全策略)
如果以MRC和ARC进行区分修饰符使用情况,可以按照如下方式进行分组:
1. MRC: assign/ retain/ copy/ readwrite、readonly/ nonatomic、atomic 等。 2. ARC: assign/ strong/ weak/ copy/ readwrite、readonly/ nonatomic、atomic 等。
属性修饰符对retainCount计数的影响。
- alloc为对象分配内存,retainCount 为1 。
- retain MRC下 retainCount + 1。
- copy 一个对象变成新的对象,retainCount为 1, 原有的对象计数不变。
- release 对象的引用计数 -1。
- autorelease 对象的引用计数 retainCount - 1,如果为0,等到最近一个pool结束时释放。
不管MRC还是ARC,其实都是看reference count是否为0,如果为0那么该对象就被释放,不同的地方是MRC需要程序员自己主动去添加retain 和 release,而ARC apple已经给大家做好,自动的在合适的地方插入retain 和 release类似的内存管理代码,具体原理如下,图片摘自官方文档。
MRC 和 ARC原理下面就详述上所列的几种属性修饰符的使用场景,应用举例和注意事项。
属性修饰符详述一、copy使用场景- 一般情况下,copy可以用于对不可变容易的属性修饰中,主要是NSArray /NSDictionary/NSString, 也可以用来修饰block。
- 在MRC和ARC下都可以使用。
- 其setter方法,与retain处理流程一样,先旧值release,再copy出新的对象。
@property (nonatomic, copy) NSString* name;
@property (nonatomic, copy) void(^typeBlock)(BOOL selected);
@property (nonatomic, copy) void(^cancelBlock)();注意事项
- 要注意的就是深浅拷贝,这个也是使用copy这个属性修饰符最重要的地方,这以后会在另一篇文章里面单独讲。
- MRC 和 ARC 都可以用copy。
- copy下的setter方法。
-(void)setName: (id)newName { if (name != newName) { [name release]; name = [newName copy]; }}
- 用copy修饰block时在MRC和ARC下的区别
MRC环境下
(1)block访问外部局部变量,block存放在栈里面。
(2)只要block访问整个app都存在的变量,那么肯定是在全局区。
(3)不能使用retain引用block,因为block不在堆区里面,只有使用copy才会把block放在堆区里面。ARC环境下
(1)只要block访问外部局部变量,block就会存放在堆区。
(2)可以使用strong去引用,因为本身就已经存放在堆区了。
(3)也可以使用copy进行修饰,但是strong性能更好。
- 当使用block的时候注意循环引用,引起内存无法释放,造成内存泄漏。
AddSignHeaderView.h文件中定义block
@property (nonatomic, copy) void (^addMembersBtnOnClick)();
AddSignViewController.m文件中调用block
// 懒加载控件- (AddSignHeaderView *)headerView { if (!_headerView) { _headerView = [[AddSignHeaderView alloc] initWithframe:CGRectMake(0, 0, ScreenWidth, 170)]; } return _headerView;}// 调用block-(void) viewDidLoad { __weak typeof(self) weakSelf = self; self.headerView.addMembersBtnonClick = ^() { AddSignContactsSelectVC *addSign = [[AddSignContactsSelectVC alloc] initWithBlockSelectedUsernames:weakSelf.contactsSource]; addSign.hidesBottomBarWhenPushed = YES; addSign.title = @"选择联系人"; addSign.delegate = weakSelf; [weakSelf.navigationController pushViewController:addSign animated:YES]; };}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)