zoukankan      html  css  js  c++  java
  • 七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 4.@property参数 5.@class和循环retain的使用 6.NSString的内存管理

    1,内存管理简单介绍

      1,为什么要有内存管理? malloc selloc dealloc```需要回头复习
        一般的内存 4s 是512m内存;6 是1024m内存;
        当内存过大时,会耗尽内存。出现程序闪退。

      2、OC内存管理的范围 :
          管理任何继承NSObject的对象,对其他的基本数据类型无效。

      3、对象类型是程序运行过程中动态分配的,存储在堆区;内存管理主要是对 堆区中的对象的内存管理。

      4、OC内存管理的原理 为了防止内存泄露
        对象的引用计数器 :
          每个OC对象都有自己的引用计数器,是一个整数表示对象被引用的次数,即现在有多少东西在使用这个对象。
          对象刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁。这个对象所对应的内存将被释放。

      5、内存管理的分类:
        MRC,手动管理;
        ARC,自动引用计数管理;

      6,内存管理的原则(必须要遵守这个原则)记住两点:

        1),谁创建(alloc,new),谁release或者autorelease;
        2),谁retain,mutableCopy(copy),谁release或autorelease;

      7、内存管理研究的内容
        1)野指针(僵尸对象)
        2)内存泄露

     2,单个对象内存管理

      1.野指针: 未初始化的指针或者所指向的内存已经被释放的指针。
       僵尸对象: 所占内存已经被回收的对象称为僵尸对象;僵尸对象不能再被使用。
       (默认情况下xcode为了提高编码效率,不会时时检查僵尸对象,所以默认不打开检测僵尸对象的选项)

       面试题:nil和Nil及NULL、NSNull的区别:

          nil: 是一个对象值;如果我们要把一个对象设置为空的时候就用nil;
            A null pointer to an Objective-C object. ( #define nil ((id)0) )
          Nil :是一个类对象的值,如果我们要把一个Class类型的对象设置为空的时候就用Nil ; A null pointer to an Objective-C class.
          NULL 是一个通用指针,向C类型的指针为空 ;A null pointer to anything else. ( #define NULL ((void *)0) )
          NSNull 在Objective-C中是一个类,它用在不能使用nil的场合;A class defines a singleton object used to represent null values in collection objects

                     (which don't allow nil values).
          [NSNull null]: The singleton instance of NSNull.
          [NSNull null]是一个对象,他用在不能使用nil的场合。

      2.内存泄露 (栈区的指向已经释放, 堆区的空间没有释放, 这时堆区的空间就被泄露了)

        泄露原因:
          1,对象创建了之后,没有release;
          2,retain 或 alloc 的总和大于 release或autorelease的和;
          3.不当的使用nil;当retainCount>0时,给对象赋值nil;
          4.在方法中对传入的对象retain了.

    3,多个对象内存管理,set方法的内存管理

      1)基本数据类型或者C语言的构造类型:直接赋值
        int float double long struct enum
        -(void)setAge:(int)age
        {
          _age=age;
        }

      2)OC对象类型
        -(void)setCar:(Car *)car
        {
          //1.先判断传进来的是不是原来的对象
          if(car!=_car){
            //2 对旧对象做一次release
            [_car release];//若没有旧对象,则没有影响
            //3.对新对象做一次retain
            _car=[car retain];

          }
        }

    4,@property参数

      1)是否要生成set方法(若为只读属性,则不生成)
        readonly:只读,只会生成getter的声明和实现
        readwrite:默认的,同时生成setter和getter的声明和实现


      2)多线程管理(苹果在一定程度上屏蔽了多线程操作)
        nonatomic:高性能,一般使用这个
        atomic:低性能,默认


      3)内存管理相关参数
        retain: 对对象release旧值,retain新值(适用于OC对象类型)
        assign: 直接赋值(默认,适用于非oc对象类型)
        copy: release旧值,copy新值
        验证assign如果作用在对象上,实际上就是直接赋值


      4)set和get方法的名称
        修改set和get方法的名称,主要用于布尔类型。因为返回布尔类型的方法名一般以is开头,修改名称一般用在布尔类型中的getter。
        @property(nonatomic,assign, setter=abc:,getter=haha)int age

        1,getter=getterName,setter=setterName,设置setter与getter的方法名,除非你想自己取名,否则一般使用默认的名字即可。以免造成混乱。
        2,readwrite,readonly (只生成getter方法),设置可供访问级别的限制。
        2,assign,调用setter方法时直接赋值,不进行任何retain操作。
        3,retain,调用setter方法时,先release旧值,然后对赋予的新值执行retain,相当于一次指针的拷贝。
        4,copy,setter方法进行Copy操作,与retain处理流程一样,先release旧值,再Copy出新的对象,retainCount为1。其实是建立一个新的对象。
        5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

    5.@class和循环retain的使用  

      1.#import和@class的区别。
        1.作用上的区别
        #import会包含引用类的所有信息(内容), 包括引用类的变量和方法
        @class仅仅是告诉编译器有这么一个类, 具体这个类里有什么信息, 完全不知

        2.效率上的区别
        如果有上百个头文件都#import了同一个文件,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍 , 编译效率非常低 相对来讲,

        使用@class方式就不会出现这种问题了

      2.循环retain的场景
        比如A对象retain了B对象,B对象retain了A对象 循环retain的弊端 这样会导致A对象和B对象永远无法释放

        循环retain的解决方案
        当两端互相引用时,应该一端用retain、一端用assign

    6.NSString的内存管理 

      NSString *testStr1 = @"a";//常量区

       NSString *testStr2 = [NSString stringWithString:@"a"];//常量区
       NSString *testStr3 = [NSString stringWithFormat:@"b"];//堆区
       NSString *testStr4 = [[NSString alloc] initWithString:@"c"];//常量区
       NSString *testStr5 = [[NSString alloc] initWithFormat:@"d"];//堆区
       NSString *testStr6 = [[NSString alloc] init];//没有意义

  • 相关阅读:
    Typora+PicGo图片上传教程
    创建一个springbootcloud项目
    plugin.xml 解析说明
    Java 元注解 使用示例
    Spring 注解学习 使用示例
    springboot2.2 集成 activity6 请假完整示例
    SpringBoot 过滤器,拦截器初步学习整理(有示例代码)
    mybatis plus mysql 代码生成器 示例demo
    Bootstrap相关方法,事件整理
    网站链接
  • 原文地址:https://www.cnblogs.com/jiayongqiang/p/5095667.html
Copyright © 2011-2022 走看看