• OC内存管理(一)


    OC内存管理:

    前言:为什么基本数据类型分配在栈区,而动态分配的内容在堆区。
    因为基本数据类型的存放的数据在内存中得大小是固定的比如int类型的数据就是分配-2^31——2^31-1。而要分配不确定的数据在内存中得话,就动态分配到堆区。
    一:基本原理
    1>为什么要进行内存管理。
       内存管理的范围是:继承自NSObjetc的类对象,对基本数据类型无效
       我们知道手机的内存非常有限,而基本数据类型在编译时会静态分配内存在栈区,当代码块结束时,栈区的成员变量自动释放,当然指向对象的指针也会被释放。而对象是在代码运行时动态分配在内存的堆区,指向对象的指针销毁,而对象会被保存在堆区,造成了内存的泄露。
     
    2>对象中得引用计数器
    每一个OC对象都有一个引用计数器,是一个整数,表示对象被引用的次数,(通俗将就是被多少指针指向)默认对象创建时,计数器的值为1,对象销毁时为0;
     每一个OC内部,默认会有4个字节的存储空间来存储引用计数器
     判断对象是否被销毁的唯一标准就是它内部的引用计数器是否为0
     
    3>内存管理的代码
      retain:表示引用计数器加1
     release:表示引用计数器减1
    retaincount:表示当前引用计数器的值。
     
    4>对象的销毁
    当一个对象的引用计数器为0时,那么这个对象就会被销毁,对象销毁的同时,系统会默认向对象发送一个dealloc方法。一般我们会重写dealloc方法,在这里释放相关的资源。一旦重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用(不能直接调用dealloc方法)。
     
    5>几个概念
    僵尸对象,已经释放内存的对象
    野指针,   指向僵尸对象的指针
    空指针,没有指向任何东西的指针(存储的东西是0,null,nil),给空指针发送消息不会报错
     
    二:内存管理原则
     
     只要还有某个指针引用着对象,这个对象就不能被回收
     如果某个指针要引用某个对象,这个对象的引用计数器就要加1
     如果某个指针不再引用这个对象,那么对象的引用计数器就要减1
     
    谁创建如alloc、new、copy来创建对象,那么就要谁release
    谁retain就是要引用,那么要谁就要release;
     
    三:内存规范代码
    1> 只要调用了alloc new copy必须release活着autorelease
    2> set方法中得代码
        基本数据类型:直接复制
    • (void)setAge:(int)age{
    • _age = age;
    • }
    • OC对象数据类型- (void)setCar:(Car *)car

      {

          // 先判断是不是新传入的对象

          if (_car!=car) {

              // 对旧的对象release

              [_car release];

              // 对新的对象retain  返回值为当前对象 - (id)retain OBJC_ARC_UNAVAILABLE;

              _car = [car retain];

          }

      }3,dealloc方法规范

    • 1>一定要调用父类的方法[super dealloc];

      2> 对self(当前)所拥有的的其他对象做一次release操作

      -(void)dealloc

      {

      [_car release];

      [super dealloc];

    • 四:property的参数
       
      1>内存管理的相关的参数
      retain: 会在set方法中编译器会自动release旧值,retain新值(针对OC对象类型
      assign:在set方法就是直接赋值(适合非OC对象,基本数据类型)
      copy: set方法中release旧值,copy新值,
      2> 是否要生成set方法(若为只读属性,则不生成)

      Readonly:只读,只会生成getter的声明和实现

      Readwrite:默认的,同时生成setter和getter的声明和实现

      3> 多线程管理(苹果在一定程度上屏蔽了多线程操作)

      Nonatomic:高性能,一般使用这个

      Atomic:低性能

      4> Setter和getter方法的名称

      修改set和get方法的名称,主要用于布尔类型。因为返回布尔类型的方法名一般以is开头,修改名称一般用在布尔类型中的getter。

      @propery(setter=setAbc,getter=isRich) BOOL rich;

      BOOL b=p.isRich;// 调用

      五:@class 用法

       @class用在.h头文件仅仅告诉编译器某个名称是一个类,当在.m中真正用到这个类的方法属性时才包含头文件声明

       应用场景及好处:1>提高编译器的编译性能 问题:当某个类被多个类头文件引用的话,当被引用的类声明有更改的话,其他的引用这个类的类也要跟着变化,造成编译器编译性能降低

       2>@class类循环引用的问题。

      六:内存管理中retain循环引用的问题

      解决方案是1,将一个类的头文件中用@class

                     2,属性包含关系中一端用retain,一端用assign(当然是要assign中不需要在dealloc中release) 

    • Person类中
    • #import "Person.h"
      #import "Dog.h"
      
      @interface Person : NSObject
      
      @property (nonatomic, assign) Dog *dog;
      
      @end
      
      @implementation Person
      
      - (void)dealloc
      {
      //    [_dog release];
          NSLog(@"person ---------dealloc");
          [super dealloc];
      }
      
      @end

      Dog类中

    • #import "Dog.h"
      @class Person;
      
      @interface Dog : NSObject
      
      @property (nonatomic, retain) Person *person;
      
      @end
      
      @implementation Dog
      
      - (void)dealloc
      {
      //    [_person release];
          self.person = nil; // _person release]   _person = nil;
          NSLog(@"dog-----------dealloc");
          [super dealloc];
      }
      
      @end

      main函数中

    • #import <Foundation/Foundation.h>
      #import "Person.h"
      #import "Dog.h"
      
      int main(int argc, const char * argv[])
      {
      
          Person *p = [[Person alloc] init];
          Dog *d = [[Dog alloc] init];
          
          p.dog = d;
          d.person = p;
          [d release];
          
          
          [p release];
          return 0;
  • 相关阅读:
    JAVA 注解的几大作用及使用方法详解
    内省、JavaBean、PropertyDescriptor类、Introspector类、BeanUtils工具包、注解、Rentention、Target、注解的基本属性和高级属性
    关于Hash集合以及Java中的内存泄漏
    ifconfig命令详情
    route命令详情
    ping命令详解
    scp命令详解
    ssh命令详解
    telnet命令详解
    sudo命令详解
  • 原文地址:https://www.cnblogs.com/-boy/p/4085898.html
Copyright © 2020-2023  润新知