OC进阶(二)

news/2024/7/20 12:30:56 标签: 内存管理, 数据结构与算法

1.autorelease注意及错误用法

#import <Foundation/Foundation.h>
#import "Person.h"
/**
 *  autorelease的使用注意
 */
void test(){

    //1 自动释放池
    Person *p = [Person new];
    @autoreleasepool {
        
        //autorelease的使用注意:
        // 1)并不是所有的放到自动释放池中的代码,产生的对象就会自动释放
        //   如果需要释放,必须加入到自动释放池
        //        Person *p = [[Person new] autorelease];
        
        //我们只需要在自动释放池代码块中调用autorelease 就可以把对象
        //加入到自动释放池
        [p autorelease];
        
    }
    
    //2) 如果对象调用了autorelease 但是,调用autorelease的时候,没有在任何一个自动释放池中,此时该对象也不会 被加入到自动释放池
    //    Person *p = [[Person new] autorelease];


}

/**
 *  自动释放池的嵌套
 */
void test2(){

    Person *p = [[Person alloc] init];
    
    [p retain];  //2
    //autoreleasepool的嵌套
    //自动释放池的栈结构(数据结构),和内存的栈区是不一样的
    // 对象存在 位于栈顶位置的自动释放池中
    @autoreleasepool {
        
        @autoreleasepool {
            
            @autoreleasepool {
                
                [p autorelease];  //20M
                
                for(int i=0;i<10000;i++){
                    
                    Person *temp = [[Person new] autorelease];
                    
                    
                }
                
                
                //1000行
                
                
                
                
            }// [p release];  //1
            
            [p autorelease];
            
        }//
        
    }

}
int main(int argc, const char * argv[]) {
    
    Person *p = [[Person alloc] init];   //1
   
    //autoreleasepool的嵌套
    //自动释放池的栈结构(数据结构),和内存的栈区是不一样的
    // 对象存在 位于栈顶位置的自动释放池中
    @autoreleasepool {
        
        
        [p autorelease];
        
    }//   [p release];    1---->0
    
    [p release]; //错误的用法
    
    
    return 0;
}

2.autorelease的应用场景

+(instancetype)person{
    //Person person  ---> Person
    //Stduent person ----> Student
    //创建对象
    return [[[self alloc] init] autorelease];  //返回的时对象的空间
    //能够帮我们把对象给加入到自动释放池

}


        //帮我们快速的创建对象,并且管理对象的内存(加入到自动释放池)
//        Person *p = [Person person];
        // 1) 创建一个对象  p
        // 2) 用完之后,系统把对象释放掉 p

3.ARC机制

/*
 
   ARC机制
 
    1) 判断是否是ARC机制
   
       查看项目信息   不能使用retain release autorelease retainCount
       在dealloc方法中不能使用 [super dealloc];
 
    2) 使用
 
       正常创建对象,不用手动释放对象
 
 */


#import <Foundation/Foundation.h>
#import "Dog.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //ARC机制下对象的释放
        Dog *jd = [Dog new];
        [jd run];
        
        
    }
    return 0;
}

4.ARC单对象内存管理

#import <Foundation/Foundation.h>
#import "Car.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //在ARC下对象释放的判断依据: 对象没有强指针指向
        //对象会立即释放内存空间
        // bigBen 强指针(指针默认的都是强指针)
        Car *bigBen = [Car new];
        //定义另外一个强指针指向
        //__strong 修饰符,修饰这个指针是一个强指针,也可以不写
        //__weak         修饰的这个指针是若指针
//        __strong Car *bmw = bigBen;
        __weak Car *bwm2 = bigBen;
        NSLog(@"bigBen = %@,bwm2 = %@",bigBen,bwm2);
        //bigBen的指向发生改变,对于Car对象来说没有强指针指向了,所以要释放对象
        
        bigBen = nil;  //
        // 要   1) bigBen 是强指针,重新指向其他内容了,对于对象来说没有强指针了
        //      2) 弱指针 赋值为nil
        
        NSLog(@"bigBen = %@,bwm2 = %@",bigBen,bwm2);
        [bwm2 run];  //[nil run];
        
        [bigBen run]; //[nil run];
        
        NSLog(@"xxxxxx");
        
    }
    return 0;
}

5.ARC多对象内存管理

int main(int argc, const char * argv[]) {
    @autoreleasepool {
    
        //
        Dog *byd = [Dog new];
        
        Person *p = [Person new];
        
        p.dog = byd;
        
//      1)在 @property (nonatomic,weak) Dog *dog;
//        byd = nil    // Dog对象会立即释放
//                     因为该对象没有强指针指向了
        
//      2)在 @property (nonatomic,strong) Dog *dog;
//        byd = nil    // Dog对象不会被立即释放
//
        byd = nil;
        
        
        
    }
    return 0;
}

6.ARC下循环引用问题

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //dog p 都是局部变量
        //局部变量的生命周期: 从定义的位置开始,到它所在的代码块"}"结束
        Dog *dog = [Dog new];
        Person *p = [Person new];
        
        //构成一个循环引用
        p.dog = dog;  //_dog weak类型
        dog.owner = p;
        
        NSLog(@"xxxxx");
        
    }
    return 0;
}

7.分类

/*
   
    分类: 
  
        一些方法的声明和实现
 
    作用: 在不修改类的源代码的前提下,给类增加新的功能
  
    使用步骤:
 
         //此处是声明一个类
         @interface Person : NSObject
 
         @end
 
         //类的实现
         @implementation Person
 
 
         @end
 
 
       1) 声明一个分类
 
          格式:
 
          @interface 待扩展的类名 (分类的名称)
 
          @end
 
          Person+base  -->分类文件的命名规则
          eat run
 
          如:
          @interface Person (base)
            //吃
             -(void)eat;
            //跑
             -(void)run;
          @end
 

 
       2) 实现这个分类
 
          格式:
 
          @implementation 待扩展的类 (分类的名称)
  
          @end
 
          如:
 
          Person+base 类别实现
          @implementation Person (base)
             //吃
             -(void)eat{
             
                NSLog(@"人会吃东西");
             }
             //跑
             -(void)run{
             
                NSLog(@"人会跑");
             
             }

          @end
 
 
 
       3) 使用分类中的方法
 
          和使用类中原有的对象一样
          Person *p = [Person new];
          [p xxx];
 
 
 
 
         playGame类别  --- 张三
         playlol  playdota
   
 
         study 类别    --- 李四
         studyc   studyios
 
 */
/*
 
    分类的使用注意事项:
 
    1) 在分类的声明中不能声明实例变量
 
        不能定义实例变量 也不能使用 @property
 
    2) 在分类的方法中,可以访问类中的实例变量
 
 
    3) 在分类中存在和类同名的方法
 
       优先访问的时 分类中 的方法
 
    4) 当在多个类别中有同名的方法的时候,这时候,执行的最后编译的那个类别的同名方法
 
       分类的 > 原类
 
       最后编译的分类 >  其他的分类 
 */
#import "Person.h"

@interface Person (playGame)
//增加一个类别,类别名称 playGame 给Person增加新的方法
-(void)playLol;
-(void)playDota;
@end
#import "Person+playGame.h"

@implementation Person (playGame)
-(void)playLol{
    
    NSLog(@"那人正在玩撸啊撸");

}
-(void)playDota{

    NSLog(@"那人正在玩刀塔");

}
@end

8.类扩展

#import "Person.h"
#import "Person_work.h"
//扩展\延展\延展分类
//延展是一个特殊的分类
//特点:
// 1) 可以在延展中 定义实例变量
// 2) 不能使用 @implementation 类名() 实现类别的方法
// 3) 作用,可以定义私有的变量和方法
@interface Person ()
{
    float _weight;
}
-(void)run;  //run 相对私有的方法
@end


@implementation Person
-(void)run{

    NSLog(@"延展的run方法 %.2f",_weight);

}
// Person_work.h 声明的,延展
-(void)work{

    NSLog(@"work %d",_height);

}
-(void)test{

    [self run];
    [self work];
}
@end

 

转载于:https://www.cnblogs.com/iosnds/p/4917208.html


http://www.niftyadmin.cn/n/667599.html

相关文章

jQuer 排他思想

<body><button>快速</button><button>快速</button><button>快速</button><button>快速</button><button>快速</button><button>快速</button><button>快速</button><script>…

RxJava 中的map与flatMap

1、map和flatMap都是接受一个函数作为参数(Func1)2、map函数只有一个参数&#xff0c;参数一般是Func1&#xff0c;Func1的<I,O>I,O模版分别为输入和输出值的类型&#xff0c;实现Func1的call方法对I类型进行处理后返回O类型数据3、flatMap函数也只有一个参数&#xff0c…

OrCAD Capture CIS与Allegro交互布局

激活OrCAD与Allegro的交互程序 1. 打开原题图&#xff0c;Options->Preference在Miscellaneous里勾选 2. 同时打开OrCAD原理图设计界面及Allegro PCB Design界面。在Allegro PCB Design里要激活Place->Manually命令&#xff0c;此时用鼠标左键选中OrCAD原理图中的元件&am…

随机生成4个验证码【包括数字或字母(大写或小写)】之总结

1、最后生成的4个随机的验证码&#xff0c;很明显是一个字符串&#xff0c;要输出一个随机验证码&#xff0c;那么需要一个字符串类型的变量来接收这个验证码 2、都转换成字符串char类型&#xff0c;最后再将随机产生的4个字符拼接起来构成4个随机的验证码 10个数字的依次遍历&…

phpMyAdmim无法打开或空白页面问题解决

环境&#xff1a;windows环境 安装方式&#xff1a;appserv 安装完appserv之后&#xff0c;发现phpMyAdmin无法打开&#xff0c;具体表现为输入root用户名和密码之后长时间无法进入管理页面或进入之后一片空白。这种情况&#xff0c;一般是localhost与127.0.0.1无法进行映射。 …

主力九大出货手法剖析

&#xff11;&#xff0e;规律性出货法。有的庄家吸引散户&#xff0c;故意每天低开&#xff0c;全天多数时间让股价低位运行&#xff0c;然后尾市拉高&#xff0c;连续数天这样&#xff0c;给自以为聪明者造成短线操作适当获得丰厚的感觉&#xff0c;一旦某天接盘众多&#xf…

BIND+MySQL

使用bind-mysql模块增加对mysql数据库的支持 简介&#xff1a;对于bind&#xff0c;如果想修改或增加dns记录&#xff0c;是直接修改文本的&#xff0c;这样的话一方面不方便管理&#xff0c;另一方面容易出错&#xff0c;如果我们增加对mysql数据库的支持&#xff0c;再配合ph…

RDD:基于内存的集群计算容错抽象

转载自&#xff1a;http://shiyanjun.cn/archives/744.html 摘要 本文提出了分布式内存抽象的概念——弹性分布式数据集&#xff08;RDD&#xff0c;Resilient Distributed Datasets&#xff09;&#xff0c;它具备像MapReduce等数据流模型的容错特性&#xff0c;并且允许开发人…