iOS前期OC训练OC_08,09内存管理

本文深入探讨了Objective-C中的内存管理机制,包括垃圾回收、手动管理引用计数(MRC)和自动引用计数(ARC)。通过示例代码演示了如何创建、管理、释放对象,并介绍了对象所有权的概念及内存管理原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//

//  main.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 Clare. All rights reserved.

//


#import <Foundation/Foundation.h>

#import "Boy.h"

#import "Girl.h"

#import "Person.h"

int main(int argc, const char * argv[]) {

//    Boy *boy = [[Boy alloc] init];

//    Girl *girl = [[Girl alloc] init];

    

//    girl.delegate = boy;

//    [girl getMarry];

    

    // 管理内存有三种方式

    // :是垃圾回收,java中常见的管理内存的方法,系统来检测对象是否被使用,是否被释放

    // :MRC手动管理引用计数,iOS管理内存的方式,程序员通过手动的方式来管理对象是否被释放

    // :ARC自动管理引用计数,基于MRC,系统自动的管理内存,今后先使用MRC,培养管理内存的习惯

    

    // 对象被创建出来之后他的引用计数retainCount就变成1

//    Boy *boy = [[Boy alloc] init];

//    NSLog(@"%ld",boy.retainCount);

//    

//    // retain:对对象的引用计数+1

//    [boy retain];

//    NSLog(@"%ld", boy.retainCount);

//    

//    [boy retain];

//    [boy retain];

//    NSLog(@"%ld", boy.retainCount);

//    [boy release];

//    NSLog(@"%ld", boy.retainCount);

//    // 对对象的引用计数-1

//    [boy release];

//    NSLog(@"%ld", boy.retainCount);

//    [boy release];

//    NSLog(@"%ld", boy.retainCount);

//    [boy release];

//    NSLog(@"%ld", boy.retainCount);

//    [boy release];

//

//    NSLog(@"%ld", boy.retainCount);

//    // 当对象的引用计数1 -> 0 的时候,会自动的调用dealloc方法,dealloc才是对应对象释放的方法

//    // 当对象调用release的时候,它的引用计数是1,这个对象就不在对它的引用计数进行-1操作,而是直接调用dealloc方法,所以我们在访问对象的引用计数还是1

//    

//    // 如果多长对对象进行释放,会造成过度释放,过度释放也是最常见的内存问题,报错一般是lldb

//    [boy release];

    

//    NSArray *arr = @[@"1", @"2", @"3", @"4"];

//    NSLog(@"%ld", arr.retainCount);

//    

//    NSString *str = @"11111";

//    NSLog(@"%ld", str.retainCount);

//    NSLog(@"%u", str.retainCount);

//    

//    NSMutableString *str2 = [NSMutableString stringWithString:@"111111"];

//    NSLog(@"%ld", str2.retainCount);

//    

//    NSDictionary *dic = @{@"1":@"2", @"3":@"4"};

//    NSLog(@"%ld", dic.retainCount);

//    

//    NSLog(@"%p", str);

//    NSLog(@"%p", str2);


    // NNString 的对象在全局静态区,它的引用计数是-1,代表正整数的最大值,其他的对象都在堆区

 

//    Boy *boy = [[Boy alloc] init];

//    

//    [boy retain];

//    [boy retain];

//    NSLog(@"%ld", boy.retainCount);

//    

//    // release马上会把对象的引用计数-1,但是autorelease会延迟对对象的计数-1

//    [boy release];

//    NSLog(@"%ld", boy.retainCount);

//    [boy autorelease];

//    NSLog(@"%ld", boy.retainCount);

//    // 自动释放池

//    // 只要对象用autoreleasepool释放会把对象放入到系统自动释放池中,等出了池子的范围,对象引用计数自动-1,这个相当于java的垃圾回收,对象释放由系统来管理

//    @autoreleasepool {

//        [boy autorelease];

//        NSLog(@"%ld", boy.retainCount);

//    }

//    NSLog(@"%ld", boy.retainCount);

    

    // 内存管理的原则:加多少,对应减多少,加减做到平衡

    

    // 对象的所有权:拥有所有权的对象都可以对他进行release

//    

//    Boy *b = [Boy boy];

//    [b retain];

//    NSLog(@"%ld", b.retainCount);

//    [b release];

    // 对象如果是我们进行alloc或者retain之后我们就获取了对象的所有权,就可以对对象进行release操作

    

    // 便利构造器在返回对象的时候会加上一个autorelease,所以用便利构造器创建对象不需要对内存进行管理

//    NSArray *arr1 = [[NSArray alloc] initWithObjects:@"1", @"2", nil];

//    NSArray *arr2 = [NSArray arrayWithObjects:@"1", @"2", nil];

    

    

    // id是泛指型指针,可以用在任何的方法中,但是instancetype代表实例类型,用在自定义初始化方法,便利构造器作为返回值类型使用,标识方法会返回一个对象回去

    

//    NSArray *arr = @[@"1", @"2", @"3", @"4"];

//    NSLog(@"%ld", arr.retainCount);

//    // NSArray *newArr = [arr copy];

//    NSArray *newArr = [NSArray arrayWithArray:arr];

//    NSLog(@"%@", newArr);

//    NSLog(@"%ld", newArr.retainCount);

//    

//    // 不可变 ->可变

//    NSMutableArray *arr1 = [NSMutableArray arrayWithArray:arr];

//    NSMutableArray *arr2 = [arr mutableCopy];

//    [arr2 addObject:@"5"];

//    NSLog(@"%@", arr2);

    

//    NSDictionary *dic = @{@"1":@"2", @"3":@"4"};

//    NSMutableDictionary *muDic = [dic mutableCopy];

//    NSLog(@"%@", muDic);

    

    // 系统的类要是实现拷贝的功能,必须先签订拷贝NSCopying的协议,然后实现对应的方法

    // 不可变的数组字典可以通过mutableCopy转换成可变的数组字典

    // mutableCopy出来的对象是可变的,copy是不可变的

    

//    Boy *boy = [Boy boyWithname:@"叶寒" hobby:@"巫妖战"];

//    Boy *newBoy = [boy copy];

//    NSLog(@"%@", newBoy.name);

//    

//    // 如果自己的类想要实现copy的功能,就必须先签订NSCopying,然后实现对应的协议方法,initWithZone,之后就可以使用copy的功能

//    

//    // boy newBoy

//    NSLog(@"%ld", boy.retainCount);

//    NSLog(@"%ld", newBoy.retainCount);

    

    // copy也可以改变引用计数,但是它改变的是新对象的引用计数,而原先的对象计数不变

    

//    Boy *boy1 = [[Boy alloc] init];

//    [boy1 retain];

//    [boy1 retain];

//    NSLog(@"%ld", boy1.retainCount);

//    NSMutableArray *arr = [NSMutableArray arrayWithObjects:boy1, nil];

//    NSLog(@"%ld", [boy1 retainCount]);

//    

//    [arr removeObjectAtIndex:0];

//    NSLog(@"%ld", boy1.retainCount);

//    // 当对象放入到容器Array或者字典中,对象会被容器进行一次持有,就是retain一次,他的引用计数会加一,主要是为了防止空指针的问题

//    // 等对象从容器中移除掉之后,相应的会-1

//    

//    Boy *b = [[Boy alloc] init];

//    // 当对象加入到数组中的时候,对象使用完了消失,一旦加入到数组中,立即释放

//    NSArray *arr1 = [NSArray arrayWithObjects:b, nil]; // 最后对象随着数组释放

//    [b release]; // 对应的是alloc1


    // 自己alloc几次自己一定要release几次还有retain也是只要是自己写的就要对应release

    

//    Boy *b = [[Boy alloc] init];

//    Girl *girl = [[Girl alloc] init];

//    b.girls = girl;

//    NSLog(@"%ld", girl.retainCount);

//    

//    Girl *girl2 = [[Girl alloc] init];

//    b.girls = girl2;

//    NSLog(@"%ld", girl.retainCount);


    Person *per = [[Person alloc] initWithName:@"星辰" age:40];

    [per.arr addObject:@"1"];

    NSLog(@"%@", per.arr);

    

    return 0;

}


//

//  Boy.h

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 Clare. All rights reserved.

//


#import <Foundation/Foundation.h>

#import "Girl.h"

@interface Boy : NSObject<GirlDelegate, NSCopying>


@property(nonatomic, retain)NSString *name;

@property(nonatomic, copy)NSString *hobby;


@property(nonatomic, retain)Girl *girls;


// 自定义的初始化方法

- (instancetype)initWithName:(NSString *)name

                       hobby:(NSString *)hobby;

// 便利构造器

+ (Boy *)boyWithname:(NSString *)name

               hobby:(NSString *)hobby;


+ (Boy *)boy;

@end


//

//  Boy.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 Clare. All rights reserved.

//


#import "Boy.h"


@implementation Boy

- (void)cook

{

    NSLog(@"烤狼肉");

}


- (void)dealloc

{

    NSLog(@"对象被释放了");

    

    // 把成员变量里的+1操作全部减去

    [_name release];

    [_girls release];

    [_hobby release];


    [super dealloc];

}


// 刚创建就释放,返回的是野指针

+ (Boy *)boy

{

    Boy *b = [[Boy alloc] init];

    return [b autorelease];

}

// id void*可以在任何方法中使用

// instancetype只能在实例中使用只能在allocinit使用,即只能在便利构造器使用或者是自定义初始化中使用

//- (instancetype);


- (id)copyWithZone:(NSZone *)zone

{

    Boy *b = [Boy allocWithZone:zone];

    b.hobby = _hobby;

    b.name = _name;

    return b;

}

- (instancetype)initWithName:(NSString *)name

                       hobby:(NSString *)hobby

{

    self = [super init];

    if (self) {

        self.name = name;

        self.hobby = hobby;

    }

    return self;

}

// 便利构造器

+ (Boy *)boyWithname:(NSString *)name

               hobby:(NSString *)hobby

{

    Boy *b = [[Boy alloc] initWithName:name hobby:hobby];

    // 写便利构造器最后别忘了autorelease

    return [b autorelease];

}


- (void)setName:(NSString *)name

{

//    if (_name != name) {      // 如果名字相等

//        [_name release];      // 先将原有的_name进行释放

//        _name = [name retain]; // 然后再对_那么进行retain

//    }

    [name retain];

    [_name release];

    _name = name;

}


@end



//

//  Girl.h

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 Clare. All rights reserved.

//


#import <Foundation/Foundation.h>

// 1.声明协议

@protocol GirlDelegate <NSObject>


@required // 必须执行的

- (void)married;


@optional // 可执行可不执行

- (void)cook;

@end

@interface Girl : NSObject


// 声明代理人属性

@property(nonatomic, assign)id<GirlDelegate>delegate;


- (void)getMarry;

@end


//

//  Girl.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 Clare. All rights reserved.

//


#import "Girl.h"


@implementation Girl

- (void)getMarry

{

    [self.delegate cook];

}

@end


//

//  Person.h

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 Clare. All rights reserved.

//


#import <Foundation/Foundation.h>


@interface Person : NSObject


@property(nonatomic, retain)NSMutableArray *arr;

@property(nonatomic, copy)NSString *name;

@property(nonatomic, assign)NSInteger age;


- (id)initWithName:(NSString *)name

               age:(NSInteger)age;

+ (Person *)personWithName:(NSString *)name

                       age:(NSInteger)age;



//

//  Person.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 Clare. All rights reserved.

//


#import "Person.h"


@implementation Person

- (id)initWithName:(NSString *)name

               age:(NSInteger)age

{

    self = [super init];

    if (self) {

        self.name = name;

        self.age = age;

//        _age = age;

        // 对象创建之后,里面的数组也会创建好,不用在外面进行创建,避免因为忘了,造成问题

        self.arr = [NSMutableArray array];

    }

    return self;

}

+ (Person *)personWithName:(NSString *)name

                       age:(NSInteger)age

{

    Person *per = [[Person alloc] initWithName:name age:age];

    return [per autorelease];

}


- (void)dealloc

{

    [_arr release];

    [_name release];

    [super dealloc];

}


@end











@end




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值