美文网首页iOS技术文章
OC:属性详解☀️

OC:属性详解☀️

作者: LeaderBiao | 来源:发表于2016-06-24 11:36 被阅读353次
    • 版权声明:本文为博主原创文章,未经博主允许不得转载。
    在开发过程中经常要用到定义属性,@property@synthesize是经常用到的关键字,那么到底该如何正确定义一个属性呢,我们需要了解其中用到的关键字。

    atomic: 原子操作(原子性是指事务的一个完整操作,操作成功就提交,反之就回滚. 原子操作就是指具有原子性的操作)在objective-c 属性设置里面默认的就是atomic,意思就是setter/getter函数是一个原子操作,如果多线程同时调用setter时,不会出现某一个线程执行完setter所有语句之前,另一个线程就开始执行setter,相当于函数头尾加了锁. 这样的话并发访问性能会比较低.

    nonatomic: 非原子操作 一般不需要多线程支持的时候就用它,这样在并发访问的时候效率会比较高. 在objective-c里面通常对象类型都应该声明为非原子性的. iOS中程序启动的时候系统只会自动生成一个单一的主线程.程序在执行的时候一般情况下是在同一个线程里面对一个属性进行操作. 如果在程序中我们确定某一个属性会在多线程中被使用,并且需要做数据同步,就必须设置成原子性的,但也可以设置成非原子性的,然后自己在程序中用加锁之类的来做数据同步.通常说nonatomic 是提高在非多线程应用中的读写效率.

    在头文件中声明属性的时候使用atomicnonatomic等价于在头文件里面添加2个函数一个是用于设置这个属性的,一个是用于读取这个属性,例如:- (nsstring *)name; - (void)setName:(NSString *)str;
    atomic / nonatomic 需要和@synthesize/@dynamic配和使用才有意义.

    @synthesize 如果不实现settergetter方法,编译器将会自动在生产settergetter方法。

    @dynamic 表示变量对应的属性访问器方法,是动态实 现的,你需要在NSObject 中继承而来的+(BOOL) resolveInstanceMethod:(SEL) sel 方法中指定动态实现的方法或者函数。

    属性修饰其他关键字:
    getter=getterName;
    指定get方法,并需要实现这个方法。必须返回与声明类型相同的变量,没有参数
    setter=setterName;
    指定set方法,并需要实现这个方法。带一个与声明类型相同的参数,没有返回值(返回空值)
    当声明为readonly的时候,不能指定set方法
    readwrite
    如果没有声明成readonly,那就默认是readwrite。可以用来赋值,也可以被赋值
    readonly
    不可以被赋值
    assign
    所有属性都默认assign,通常用于标量(简单变量 int, float,CGRect等),只是简单的传递指针.
    一种典型情况是用在对对象没有所有权的时候,通常是delegate,避免造成死循环(如果用retain的话会死循环)
    retain
    属性必须是objc对象,拥有对象所有权,必须在dealloc中release一次,是在传递指针后 retainCount +1。
    copy
    属性必须是objc对象,拥有对象所有权,必须在dealloc中release一次。且属性必须实现NSCopying协议
    一般常用于NSString类型,是创建分配一个新的空间,从原址的内容复制内容过来.```
     
    ######dealloc 后relase的事情,建议是在每个 object的 m文件里 成对的创建和销毁变量.谁创建,谁负责销毁,谁retain 谁来release.
    
    
    #####`@property`是一个属性访问声明,扩号内支持以下几个属性:
    
    

    1,getter=getterName,setter=setterName,设置setter与getter的方法名
    2,readwrite,readonly,设置可供访问级别
    3,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
    4,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)
    5,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
    6,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级。```

    @synthesize xxx; 为这个新属性自动生成读写函数;

    如果你不懂怎么使用他们,那么就这样 ->
    使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)
    使用copy: 对NSString
    使用retain: 对其他NSObject和其子类
    

    当你定义了一系列的变量时,需要写很多的gettersetter方法,而且它们的形式都是差不多的,,所以Xcode提供了@property@synthesize属性,@property用在 .h 头文件中用作声明,@synthesize用在.m 文件中用于实现。
    如下,新建一个基于“Command Line Tool”的项目,名为“property”,再新建一个Student类,传统的写法是:

    Student.h
    
    //  
    //  Student.h  
    //  property  
    //  
    //  Created by Biao on 16-4-22.  
    //  Copyright (c) 2016年 Biao. All rights reserved.  
    //  
      
    #import <Foundation/Foundation.h>  
      
    @interface Student : NSObject  
    {  
        int age;  
        int no;  
    }  
      
    //age的getter和setter方法声明  
    - (int)age;  
    - (void)setAge:(int)newAge;  
      
    //no的getter和setter方法声明  
    - (int)no;  
    - (void)setNo:(int)newNo;  
      
    @end  
    
    
    Student.m
    
    
    //  
    //  Student.m  
    //  property  
    //  
    //  Created by Biao on 16-4-22.  
    //  Copyright (c) 2016年 Biao. All rights reserved.  
    //  
      
    #import "Student.h"  
      
    @implementation Student  
      
    //age的getter和setter方法的实现  
    - (int)age  
    {  
        return age;  
    }  
    -(void)setAge:(int)newAge  
    {  
        age = newAge;  
    }  
      
    //no的getter和setter方法的实现  
    - (int)no  
    {  
        return no;  
    }  
    - (void)setNo:(int)newNo  
    {  
        no = newNo;  
    }  
      
    @end  
    
    
    main.m
    
    //  
    //  main.m  
    //  property  
    //  
    //  Created by Biao on 16-4-22.  
    //  Copyright (c) 2016年 Biao. All rights reserved.  
    //  
      
    #import <Foundation/Foundation.h>  
    #import "Student.h"   
      
    int main(int argc, const char * argv[])  
    {  
      
        @autoreleasepool {  
              
            // insert code here...  
            Student *stu = [[Student alloc] init];  
            stu.age = 100;//这句相当于setter方法  
            NSLog(@"age is %i", stu.age);//这里的 stu.age 相当于getter方法            
        }  
        return 0;  
    }  ```
    
    >用@property和@synthesize的写法是:
    
    

    Student.h

    //
    // Student.h
    // property
    //
    // Created by Biao on 16-4-22.
    // Copyright (c) 2016年 Biao. All rights reserved.
    //

    import <Foundation/Foundation.h>

    @interface Student : NSObject
    {
    int age;
    int no;
    }

    //当编译器遇到@property时,会自动展开成getter和setter的声明
    @property int age;
    @property int no;

    @end

    Student.m

    //
    // Student.m
    // property
    //
    // Created by Biao on 16-4-22.
    // Copyright (c) 2016年 Biao. All rights reserved.
    //

    import "Student.h"

    @implementation Student

    //@synthesize 会自动生成getter和setter的实现
    //@synthesize 默认会去访问age,no,height同名的变量,,
    //如果找不到同名的变量,会在内部自动生成一个私有同名变量age,no,height,,
    //因此Student.h 中的这几个变量也可以省略不写。
    @synthesize age,no;

    @end

    main.m

    //
    // main.m
    // property
    //
    // Created by Biao on 16-4-22.
    // Copyright (c) 2016年 Biao. All rights reserved.
    //

    import <Foundation/Foundation.h>

    import "Student.h"

    int main(int argc, const char * argv[])
    {

    @autoreleasepool {  
          
        // insert code here...  
        Student *stu = [[Student alloc] init];  
        stu.age = 100;  
        NSLog(@"age is %i", stu.age);  
          
    }  
    return 0;  
    

    } ```

    几点说明:
    1.在Xcode4.5及以后的版本中,可以省略@synthesize ,编译器会自动帮你加上getter 和 setter 方法的实现,并且默认会去访问_age这个成员变量,如果找不到_age这个成员变量,会自动生成一个叫做 _age的私有成员变量。
    2.建议变量名用"_"前缀作为开头。

    相关文章

      网友评论

        本文标题:OC:属性详解☀️

        本文链接:https://www.haomeiwen.com/subject/klpodttx.html