Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 320|回复: 0

[默认分类] Object c的set和get方法,ARC和MRC 下面的实现

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-4-26 10:47:32 | 显示全部楼层 |阅读模式

    ARC 下面的实现:
    首先是创建一个person的类,
    然后声明set方法和get方法
    有规则是,set方法的名字后面就是变量的,setName
    get方法直接就用变量名去掉下划线

      
       
        [csharp]
        view plain
         copy
         
       
      
      
       //  
       //  Person.h  
       //  SetAndGetDemo  
       //  
       //  Created by 千 on 16/9/11.  
       //  Copyright © 2016年 kodulf. All rights reserved.  
       //  
       
       #import <Foundation/Foundation.h>  
         
       @interface Person : NSObject  
       {  
           NSString *_name;  
           CGFloat _age;  
       }  
       -(void)setName:(NSString *)name;//set后面是变量的首字母大写的,后面的参数是去掉下划线的名字  
       -(void)setAge:(CGFloat)age;  
       //get方法要注意返回的值,不用像set一样,不用写get,直接写,例如要获取变量_name就是name  
       -(NSString *)name;  
       -(CGFloat)age;  
         
       @end  
      


    然后在m的文件中实现:

      
       
        [csharp]
        view plain
         copy
         
       
      
      
       //  
       //  Person.m  
       //  SetAndGetDemo  
       //  
       //  Created by 千 on 16/9/11.  
       //  Copyright © 2016年 kodulf. All rights reserved.  
       //  
       
       #import "Person.h"  
         
       @implementation Person  
       -(void)setName:(NSString *)name{  
           _name=name;  
       }  
       -(void)setAge:(CGFloat)age{  
           _age=age;  
       }  
         
       -(NSString *)name{  
           return _name;  
       }  
         
       -(CGFloat)age{  
           return _age;  
       }  
         
       - (NSString *)description  
       {  
           return [NSString stringWithFormat:@"name=%@,age=%f",_name,_age];  
       }  
       @end  
      


    最后在main的函数中应用

      
       
        [csharp]
        view plain
         copy
         
       
      
      
       //  
       //  main.m  
       //  SetAndGetDemo  
       //  
       //  Created by 千 on 16/9/11.  
       //  Copyright © 2016年 kodulf. All rights reserved.  
       //  
       
       #import <Foundation/Foundation.h>  
       #import "Person.h"  
         
       void print(Person *person){  
           NSLog(@"%@",person);  
           NSLog(@"person name=%@,person age=%f",[person name],[person age]);  
       }  
       int main(int argc, const char * argv[]) {  
           @autoreleasepool {  
               // insert code here...  
               NSLog(@"Hello, World!");  
               Person *person = [Person new];  
                
               print(person);  
               [person setAge:1.7];  
               [person setName:@"设置的名字"];  
               print(person);  
           }  
           return 0;  
       }  
      





    MRC:
      首先要改arc的改成no,就是build setting那里的gar改成no
      编译一下就是在我们的mrc的环境下了
      。m文件中的set方法的实现逻辑就不能是简单的赋值了,我们这样的操作,你们只是完成了地址的简单传递,并不能去持有我们这个对象的绝对使用权。所以为了能让我们保证我们操作对象的声明周期在我们使用期间一直存在,我们必须去使用我们内存管理中的retain方法进行对象的一个强引用,首先我们在这里先回顾一下,内存管理原则,创建person使用了alloc了,那么是不是要在我们下面对应的位置,也就是我们person这个对象使用完成之后,我们对应要进行一个release,这样才能保证我们的内容不被泄漏,除此之外,我们来看看
      _name =[name retain]我们必须调用对象的强引用来保证我们使用期间,对象是一只存在的。
      好的,我们大家可以看到,这里面又出现了我们内存管理原则里面的一个方法了
      有了强引用之后,我们使用完了之后,就要在相应的位置上进行一个release
      这里面,我们在类的内部,一般去释放我们的对象,我们都要写在dealloc里面
      它和我们person的生命周期进行一个同步,这个是我们setname这个方法,有了这样一个强引用之后,我们再来看下面:
      有了这样一个强应用之后,我们假设外部两次的赋值结果都是相同的值,那么我们就可以考虑一下,第二次赋值,让他不再走retain的逻辑,节省一下我们的执行逻辑
      所以这里可以像下面一样添加一个判断
      -(viod)dealloc{
         [_name release];
         [super dealloc];
      }
      -(void)setName:(NSString *)name{
         if(name!=_name){
             _name = [name retain];
         }
      }
      
      除此之外,我们还要注意,如果我们第二次再次赋值的时候
      我们肯定要写一个[_name release]先完成对上一次之前的赋值结果的成功的让它释放掉,接下来我们才对新值进行retain,这样才能够保证,我们的内存不至于去泄漏
      如果不添加release这句话的话,那么上一你去强引用的对象,你直接给他人掉了,没有人去管它了,这样我们的内存就会泄漏了
      -(viod)dealloc{
      [_name release];
      [super dealloc];
      }
      -(void)setName:(NSString *)name{
      if(name!=_name){
      [_name release]
      _name = [name retain];
      }
      }
      我们看下面的这两个方法,setAge不用管,因为是基本数据类型,
      setSex的方法,我们直接复制上面的代码到这里,然后修改相应的变量
      - (void)setAge:(NSUInteger) age{
         _age = age;
      }
      - (void)setSex:(NSString *)sex{
         _sex = sex;
         if(sex!=_sex){
             [_sex release]
             _sex = [sex retain];
         }
      }
      
      不要忘记在上面的dealloc里面也要对我们的_sex进行release
      -(viod)dealloc{
      [_name release];
      [_sex release];
      [super dealloc];
      }
      
      所以可以看到,在mrc模式下,我们需要考虑的逻辑很多,我们要考虑:
      考虑内存是否每一步都做到一个平衡管理,所以可以看到,
      当我们在不同的文件,不同的代码逻辑中去使用我们mrc内存管理,你很可能会有内存泄露哦的地方,这也是我们苹果公司后续支持arc的一个原因
      在我们mrc下,我们的get方法和我们的arc下面是一样的,就是
      
      
    首先我们去惦记一个
    product
    ,点击
    analyze
    看一下有没有内存泄漏,没有的话,我们运行程序
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-16 19:31 , Processed in 0.372570 second(s), 47 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表