zoukankan      html  css  js  c++  java
  • ios修饰符

    1:assgin

    简单的赋值 不更改索引计数  一般修饰的是基本的数据类型 如:NSIntger,CGFloat,int,float,double,char 这里要知道 基本的数据类型是分配在栈上的 栈的内存会由系统自己处理

    //写法:
    @property (nonatomic,assign) float number;
    
    //setter方法:
    -(void)setNumber:(float)num{
      number = num;
    }

    注:assgin 也可以修饰对象;一般情况下不会使用,是因为被assgin 修饰的对象在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil,从而引起也指针的问题。对象一般分配在堆上的某块内存,如果在后续的内存分配中,刚好分配到了这块地址,程序就会crash

    2:copy

    一般情况下,copy可以用于对不可变的属性修饰中,主要是NSArray /NSDictionary/NSString, 也可以用来修饰block。

    //写法
    @property (nonatomic, copy) NSString* name;
    @property (nonatomic, copy) void(^typeBlock)(BOOL selected);
    @property (nonatomic, copy) void(^cancelBlock)();
    
    //setter方法
    -(void)setName: (id)newName {
          if (name != newName) {
            [name release];
            name = [newName copy];
         }
    }

    注:使用copy这个属性修饰符是浅拷贝,给新的对象B赋值该name属性后,B对象值更改后name属性的值不会改变。(如果使用strong修饰了name属性,B对象的值被修改了以后name的值也会变)

    3:retain

    retain修饰的对象,引用计数会+1,retain一般用来修饰非NSString 的NSObject类和其子类,retain只能修饰oc对象,不能修饰非oc对象,比如说CoreFoundation对象就是C语言框架,它没有引用计数,也不能用retain进行修饰

    //定义
    @property (nonatomic, retain) PopObject *popObject;
    
    //setter方法
    -(void) setName: (id) nameStr
    {
          if (name != nameStr) {
            [name release];
            name = [nameStr retain];
         }
    }

    注:两个对象A和B,如果A对象中引用B对象,并且用retain修饰;B对象中引用A对象,并且也用retain修饰。这个时候就是A和B相互引用,无法释放,造成内存泄漏。当泄漏严重时将会出现崩溃等问题。

    解决办法:相互引用,一端用retain,一端用assign

    4:strong

    strong表示对对象的强引用,引用计数也会+1,用于可变的数组字典字符串,或者view控件等

    两个对象之间相互强引用造成循环引用,内存泄漏。

    //使用
    @property (nonatomic, strong) NSArray  *arr;
    @property (nonatomic, strong) NSMutableArray *mArray;
    @property (nonatomic, strong) UILabel *label;
    @property (nonatomic ,strong) NSString *str;
    5:weak

    weak 表示对对象的弱引用,被weak修饰的对象随时可被系统销毁和回收,引用计数不会加1,比较常用的地方就是delegate属性的设置。

    常见的修饰符问题:

    assign和weak的区别:当它们指向的对象释放以后,weak会被自动设置为nil,而assign不会,所以会导致野指针的出现,可能会导致crash。

    strong和weak的区别:

    • strong :表明是一个强引用,相当于MRC下的retain,只要被strong引用的对象就不会被销毁,当所有的强引用消除时,对象的引用计数为0时,对象才会被销毁。
    • weak : 表明是一个弱引用,相当于MRC下的assign,不会使对象的引用计数+1。

    两个不同对象相互strong引用对象,会导致循环引用造成对象不能释放,造成内存泄漏。


    6:nonatomic/atomic
      nonatomic 非原子属性。它的特点是多线程并发访问性能高,但是访问不安全;与之相对的就是atomic,特点就是安全但是是以耗费系统资源为代价,所以一般在工程开发中用nonatomic的时候比较多。
      系统默认的是atomic,为setter方法加锁,而nonatomic 不为setter方法加锁。
    使用atomic加锁后setter函数会变成这样,之所以这么做,是因为防止在写未完成的时候被另外一个线程读取,造成数据错误
    {lock}
        if (property != newValue) {
             [property release];
             property = [newValue retain];
         }
    {unlock}
    

      为什么nonatomic要比atomic快。原因是:它直接访问内存中的地址,不关心其他线程是否在改变这个值,并且中间没有死锁保护,它只需直接从内存中访问到当前内存地址中能用到的数据即可(可以理解为getter方法一直可以返回数值,尽管这个数值在cpu中可能正在修改中)

      为什么也经常听到有人说atomic也不是绝对安全的呢。因为:atomic的安全只是在getter和setter方法的时候是原子操作,是安全的。但是其他方面是不在atomic管理范围之内的,例如变量cnt的++运算。这个时候不能保证安全。

    @property  int height;
        @synthesize height = _height;
        self.height = 0;
        for (i = 0; i < n; i++) {
          self.height ++;
        }
    

      常见问题

      1。block为什么使用copy?block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在ARC中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。

     
  • 相关阅读:
    GoogleCpp风格指南 8)格式 _part1
    软考缉捕令
    nfc开发
    MFC 小知识总结二
    B
    UVA 10090 Marbles(扩展欧几里得)
    Android指令处理流程源代码追踪
    c语言基础学习04_条件判断语句
    教你如何解决Sublime Text 3使用中出现的中文乱码问题
    SecureCRT连接虚拟机中的Linux系统(Ubuntu)_Linux教程
  • 原文地址:https://www.cnblogs.com/huangzhenwei/p/9929548.html
Copyright © 2011-2022 走看看