iOS中属性修饰符的作用?

iOS中属性修饰符的作用?,第1张

iOS中属性修饰符的作用?

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计数的影响。

  1. alloc为对象分配内存,retainCount 为1 。
  2. retain MRC下 retainCount + 1。
  3. copy 一个对象变成新的对象,retainCount为 1, 原有的对象计数不变。
  4. release 对象的引用计数 -1。
  5. autorelease 对象的引用计数 retainCount - 1,如果为0,等到最近一个pool结束时释放。

不管MRC还是ARC,其实都是看reference count是否为0,如果为0那么该对象就被释放,不同的地方是MRC需要程序员自己主动去添加retain 和 release,而ARC apple已经给大家做好,自动的在合适的地方插入retain 和 release类似的内存管理代码,具体原理如下,图片摘自官方文档。

MRC 和 ARC原理

下面就详述上所列的几种属性修饰符的使用场景,应用举例和注意事项。

属性修饰符详述一、copy使用场景
  1. 一般情况下,copy可以用于对不可变容易的属性修饰中,主要是NSArray /NSDictionary/NSString, 也可以用来修饰block。
  2. 在MRC和ARC下都可以使用。
  3. 其setter方法,与retain处理流程一样,先旧值release,再copy出新的对象。
应用举例

@property (nonatomic, copy) NSString* name;

@property (nonatomic, copy) void(^typeBlock)(BOOL selected);

@property (nonatomic, copy) void(^cancelBlock)();

注意事项
  1. 要注意的就是深浅拷贝,这个也是使用copy这个属性修饰符最重要的地方,这以后会在另一篇文章里面单独讲。
  2. MRC 和 ARC 都可以用copy。
  3. copy下的setter方法。
-(void)setName: (id)newName {      if (name != newName) {        [name release];        name = [newName copy];     }}
  1. 用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性能更好。

  1. 当使用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];    };}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4879028.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-11
下一篇 2022-11-11

发表评论

登录后才能评论

评论列表(0条)

保存