• Objective-C中的@Property详解


    Objective-C中的@Property详解

    @Property (属性) class vairs

    这个属性有nonatomic, strong, weak, retain, copy等等

    我把它们分为三类,分别是:原子性,存取器控制,内存管理。

    原子性

    • atomic(默认):atomic意为操作是原子的,意味着只有一个线程访问实例变量。atomic是线程安全的,至少在当前的存取器上是安全的。它是一个默认的特性,但是很少使用,因为比较影响效率,这跟ARM平台和内部锁机制有关。
    • nonatomic:nonatomic跟atomic刚好相反。表示非原子的,可以被多个线程访问。它的效率比atomic快。但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。

    存取器控制

    • readwrite(默认):readwrite是默认值,表示该属性同时拥有setter和getter。
    • readonly: readonly表示只有getter没有setter。

    有时候为了语意更明确可能需要自定义访问器的名字:

    @property (nonatomic, setter = mySetter:,getter = myGetter ) NSString *name;

    最常见的是BOOL类型,比如标识View是否隐藏的属性hidden。可以这样声明:

    @property (nonatomic,getter = isHidden ) BOOL hidden;

    内存管理

    @property有显示的内存管理策略。这使得我们只需要看一眼@property声明就明白它会怎样对待传入的值。

    assign

    assign(默认):assign用于值类型,如int、float、double和NSInteger,CGFloat等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的delegate。
    @property(nonatomic) int running;
    @property(nonatomic,assign) int running;
    以上两段代码是相同的。

    在setter方法中,采用直接赋值来实现设值操作:

    -(void)setRunning:(int)newRunning{  
        _running = newRunning;  
    } 

    retian

    retian:在setter方法中,需要对传入的对象进行引用计数加1的操作。
    简单来说,就是对传入的对象拥有所有权,只要对该对象拥有所有权,该对象就不会被释放。如下代码所示:

    -(void)setName:(NSString*)_name{  
         //首先判断是否与旧对象一致,如果不一致进行赋值。  
         //因为如果是一个对象的话,进行if内的代码会造成一个极端的情况:当此name的retain为1时,使此次的set操作让实例name提前释放,而达不到赋值目的。  
         if ( name != _name){  
              [name release];  
              name = [_name retain];  
         }  
    } 

    copy

    copy:在setter方法中,首先复制传入的参数,然后将原来的旧值release,新的数值复制上去。

     -(void)setName:(NSString*)newName{
    
        if(newName!=name){
            [name release];
            name=[newName  copy];
        }
    }

    注意:Foundation中可复制的对象,当我们copy的是一个不可变的对象的时候,它的作用相当与retain(cocoa做的内存优化)比如我们对NSString进行copy,copy得到的地址是不变的。
    下面四段代码中,第一段显示的结果不会copy,而是retain.

        NSLog(@"====================================================================================");
        NSString *sstr = [NSString stringWithFormat:@"dfa"];
        NSLog(@"strassign:%p,    count:%ld", sstr , [sstr retainCount]);
        NSString *sstr2 = [sstr copy];
        NSLog(@"strassign:%p,    count:%ld", sstr2 , [sstr2 retainCount]);
        NSLog(@"====================================================================================");
    
    
        NSLog(@"====================================================================================");
        NSString *sstr = [NSString stringWithFormat:@"dfa"];
        NSLog(@"strassign:%p,    count:%ld", sstr , [sstr retainCount]);
        NSString *sstr2 = [sstr mutableCopy];
        NSLog(@"strassign:%p,    count:%ld", sstr2 , [sstr2 retainCount]);
        NSLog(@"====================================================================================");
    
    
        NSLog(@"====================================================================================");
        NSMutableString *str = [NSMutableString stringWithFormat:@"dfa"];
        NSLog(@"strassign:%p,    count:%ld", str , [str retainCount]);
        NSMutableString *str2 = [str copy];
        NSLog(@"strassign:%p,    count:%ld", str2 , [str2 retainCount]);
        NSLog(@"====================================================================================");
    
        NSLog(@"====================================================================================");
        NSMutableString *str = [NSMutableString stringWithFormat:@"dfa"];
        NSLog(@"strassign:%p,    count:%ld", str , [str retainCount]);
        NSMutableString *str2 = [str mutableCopy];
        NSLog(@"strassign:%p,    count:%ld", str2 , [str2 retainCount]);
        NSLog(@"====================================================================================");
    

    strong

    strong:strong是在IOS引入ARC的时候引入的关键字,是retain的一个可选的替代。表示实例变量对传入的对象要有所有权关系,即强引用。strong跟retain的意思相同并产生相同的代码,但是语意上更好更能体现对象的关系。

    weak

    weak:在setter方法中,需要对传入的对象不进行引用计数加1的操作,和assign相似。
    简单来说,就是对传入的对象没有所有权,当该对象引用计数为0时,即该对象被释放后,用weak声明的实例变量指向nil,即实例变量的值为0。

    强引用(strong)和弱引用(weak)的一个笑话(便于理解)

    把对象想象成一条狗,它要跑 (be deallocated)。强指针就像一条拴在狗脖子上的狗链;只要攥在手里,狗就跑不了;如果5个人攥着5条狗链都拴着狗 (5个强指针指向对象),除非5条狗链都撒开,狗就跑不了。弱指针就像是孩子指着狗喊“看!狗!”;只要狗链还拴着狗,孩子就能指着狗喊。当所有狗链都撒开,不管有多少孩子指着狗喊,狗都跑了。当最后一个强指针不再指向对象,对象就会被释放,所有弱指针清零。我们什么时候使用弱指针呢?只有当你想避免保留循环 (retain cycles,) 时,我们才使用它。

  • 相关阅读:
    mac os x 之通过远程主机在nginx上部署web静态页面
    基于jQuery UI的调色板插件推荐colorpicker
    Mac 访问隐藏文件方法! 网上方法在我电脑上都不可用!
    JavaScript设计模式学习之单例模式
    由一篇博文做出的代码,不用Math.round()如何实现其功能
    mac os x之解决npm安装包失败,或者nodejs工程缺少依赖
    用nginx的反向代理机制解决前端跨域问题
    mac之os x系统下搭建nodejs+express4.x+mongodb+gruntjs整套前端工程
    sourcetree window10 闪退
    滚动条自定义样式
  • 原文地址:https://www.cnblogs.com/AbeDay/p/5026896.html
Copyright © 2020-2023  润新知