内存管理里的一些小细节

本文探讨了Objective-C中的内存管理机制,特别是自动引用计数(ARC)如何简化内存管理任务。文章详细介绍了不同初始化方法的区别,以及如何正确创建和管理对象。此外,还讨论了在子类中使用类方法可能遇到的问题及解决方案。

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

我们有时候会看到下面的用法

    NSString *nameA = [[NSString alloc]init];
    
    NSString *nameB = [NSString string];
    
    NSString *nameC = [NSString stringWithFormat:@"%d",1];

在手动内存管理的时候

对于nameA我们需要调用release或者autorelease

对于内存管理的原则遵循,nameB、nameC我们无需调用release和autorelease

我们不需要调用,并不说明没有调用

我们来看一下,大体就是一下方式实现的

//
//  Person.h
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/26.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import <Foundation/Foundation.h>


@interface Person : NSObject

@property (nonatomic,retain)NSString *name;

+ (id)person;

+ (id)personWithName:(NSString *)name;

@end
//
//  Person.m
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/26.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import "Person.h"
@implementation Person

-(void)dealloc{
    
    NSLog(@"Person释放");
    [super dealloc];
}

+ (id)person{
    return [[[Person alloc]init]autorelease];
}
+ (id)personWithName:(NSString *)name{
    Person *person = [Person person];
    person.name = name;
    
    return person;
}
@end

//
//  main.m
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/24.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Person.h"

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

    @autoreleasepool {
        Person *personY = [[Person alloc]init];
        [personY release];//手动release
        Person *personX = [[[Person alloc]init]autorelease];//添加到自动释放池中
        Person *personA = [Person person];//类方法实现了alloc和autorelease
        Person *personB = [Person personWithName:@"LMC"];//类方法实现了alloc和autorelease
    }
    
    return 0;
}

输出:

2015-09-27 11:53:06.983 OCStudy[6563:5363578] Person释放
2015-09-27 11:53:06.984 OCStudy[6563:5363578] Person释放
2015-09-27 11:53:06.984 OCStudy[6563:5363578] Person释放
2015-09-27 11:53:06.985 OCStudy[6563:5363578] Person释放

我们看到上面的代码,表面上看 我们没有使用alloc生成对象的方法,其实是类方法,类方法中为我们已经实现了alloc和autorelease,所以不用我们手动的去调用


对于上面类方法的写法还存在一点问题

对于子类的调用上会有问题,如下

//
//  LMC.h
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/27.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import "Person.h"

@interface LMC : Person

@property (nonatomic,assign)int age;

@end
//
//  LMC.m
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/27.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import "LMC.h"

@implementation LMC

@end

上面我们做了一个Person的子类LMC

LMC中我们有个属性年龄age

我们写一下测试代码

//
//  main.m
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/24.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "LMC.h"
int main(int argc, const char * argv[]) {

    @autoreleasepool {

        LMC *lmc = [LMC personWithName:@"LMC"];
        lmc.name = @"Ryoma";
        lmc.age = 26;
    }
    
    return 0;
}

输出:


是什么原因呢?

原因就在于

LMC *lmc = [LMC personWithName:@"LMC"];

+personWithName:返回的是Person的一个对象所以我们使用的lmc也是person对象

我们断点执行如下


方案1:

//
//  LMC.m
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/27.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import "LMC.h"

@implementation LMC
+(id)person{
    return [[[LMC alloc]init]autorelease];
}
+(id)personWithName:(NSString *)name{
    LMC *lmc = [LMC person];
    lmc.name = name;
    return lmc;
}
@end

我们重写person的方法,返回LMC

方案2:

//
//  Person.m
//  OCStudy
//
//  Created by LiuMingchuan on 15/9/26.
//  Copyright © 2015年 LMC. All rights reserved.
//

#import "Person.h"
@implementation Person

-(void)dealloc{
    
    NSLog(@"Person释放");
    [super dealloc];
}

+ (id)person{
    return [[[self alloc]init]autorelease];
}
+ (id)personWithName:(NSString *)name{
    Person *person = [self person];
    person.name = name;
    
    return person;
}
@end
使用self关键字,当前谁调用这个方法self就是谁


输出:

2015-09-27 12:28:50.597 OCStudy[6710:5502268] Person释放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值