Object c的set和get方法,ARC和MRC 下面的实现

本文对比了ARC(Automatic Reference Counting)与MRC(Manual Retain Counting)两种模式下Objective-C内存管理的区别。在MRC模式中,通过手动使用retain和release来管理对象的生命周期,确保内存的合理利用并避免内存泄漏。

ARC 下面的实现:

首先是创建一个person的类,

然后声明set方法和get方法

有规则是,set方法的名字后面就是变量的,setName

get方法直接就用变量名去掉下划线

//
//  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的文件中实现:

//
//  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的函数中应用

//
//  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看一下有没有内存泄漏,没有的话,我们运行程序,

 




ARC即自动引用计数(Automatic Reference Counting),是iOS开发中编译器自动管理内存的一种机制;MRC即手动引用计数(Manual Reference Counting),需要开发者手动管理对象的内存,通过引用计数器来决定对象的生命周期 [^1][^2][^3]。 ARCMRC的区别主要体现在内存管理方式开发者操作上。在MRC中,开发者需要手动管理对象的引用计数,当创建一个对象时,引用计数加1,当不再使用该对象时,需要手动调用`release`方法使引用计数减1,当引用计数为0时,对象被释放。例如在MRC下的`dealloc`方法中,需要释放自身的实例变量、移除观察者、停止timer、移除通知、代理置空等,并且一定要在最后写`[super dealloc];` 。而在ARC下,编译器会自动插入内存管理的代码,系统会帮助释放对象所包含的实例变量,但有些对象仍需开发者手动释放,如Core Foundation框架下的一些对象,同时也需要手动进行通知中观察者的移除、代理置空、停止timer等操作 [^2]。 在使用场景方面,对于新项目开发,建议使用ARC,因为它能减少开发者手动管理内存的工作量,降低内存泄漏的风险,提高开发效率。而对于一些老项目,可能由于历史原因采用了MRC,如果要将其迁移到ARC,需要提前让团队成员了解代码迁移的方法,并且在团队层面做好意识能力上的准备,否则后续开发可能会出现问题 [^1]。 以下是ARCMRC下不同操作的代码示例: #### MRC下`dealloc`方法示例 ```objc - (void)dealloc { // 释放自身的实例变量 [_myObject release]; // 移除观察者 [[NSNotificationCenter defaultCenter] removeObserver:self]; // 停止timer [_myTimer invalidate]; _myTimer = nil; // 代理置空 self.delegate = nil; [super dealloc]; } ``` #### ARC下手动释放Core Foundation对象示例 ```objc CFStringRef cfString = CFStringCreateWithCString(kCFAllocatorDefault, "Hello", kCFStringEncodingUTF8); // 使用cfString // ... // 手动释放Core Foundation对象 CFRelease(cfString); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值