C内存管理
1.学习内存管理的目的?
①设备内存有限,如果不进行合理内存管理,内存会越积越多,最终导致程序崩溃;
②必须掌握的知识,提高程序稳定性/健壮性。
2.C中的内存管理
C中堆空间由程序员手动(coding)创建,也由程序员手动释放,确保堆空间正确释放,称为内存管理。
3.内存管理常见的错误
【内存泄漏】内存空间使用完毕之后没有被释放,造成内存堆积,达到一定程度程序崩溃
【提前释放】释放了一个正在使用的内存空间,造成数据不安全【重复释放】释放了一个已经释放的空间,造成程序崩溃
4.C传统内存管理的弊端
①释放一个堆,必须保证所有的使用堆的指针都结束使用,避免提前释放;
②确保指向同一个堆的指针,只有一个被释放,避免重复释放;
③模块化分工编程,不好确定谁来释放对象内存泄漏;
④多线程操作,不能确定哪个线程最后结束。
5.C内存管理
main.m文件
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
char * p = malloc(100);//开辟堆空间
p[45] = 7;
free(p);//释放内存
return 0;
}
OC中内存管理
1.OC中对C进行了改进,运用了内存计数的方式
OC每个类都是NSObject子类,因此每个对象都有一个内置计数器,这个计数器称为引用计数 (Reference Count) ,也称为保留计数 (Retain Count)。OC计数的机制,即 +1 和 -1 的操作。当count >= 1,表示内存空间仍被使用。当count = 0,表示对象销毁,释放内存空间。
2.OC内存管理的本质
维护计数器正确的 +1 和 -1 操作,从而使得对象正确释放。
3.OC内存管理黄金法则
①凡是用alloc,retain,new,copy,mutableCopy或以copy开头,以mutableCopy开头的方法(创建)的对象,都需要release或者autorelease进行释放。
②个人顾个人原则,谁[创建],谁释放
4.设置手动内存管理
Project –> Build Settings,在搜索框搜索gar,修改BOO值为NO
①新建ChatRoom类
ChatRoom.h
#import <Foundation/Foundation.h>
@interface ChatRoom : NSObject
- (void)talking;
@end
ChatRoom.m
#import "ChatRoom.h"
@implementation ChatRoom
- (void)talking {
NSLog(@"快要元旦了");
}
@end
②main.m
#import <Foundation/Foundation.h>
#import "ChatRoom.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
ChatRoom * xiaoliang = [[ChatRoom alloc] init];
[xiaoliang talking];
ChatRoom * xiaohong = [xiaoliang retain];
/**
* 内存管理的方式
* /不需要时刻关注,内存的引用计数到底是多少,计数做的只有+1/-1。参考黄金法则:谁创建alloc(+1) ,谁release(-1),配对存在,这样才保证了内存平衡
*/
}
return 0;
}
5.dealloc析构方法
①创建Student类
Student.h
#import <Foundation/Foundation.h>
@interface Student : NSObject {
NSMutableArray * _array;
}
- (Student *)init;
@end
Student.m
#import "Student.h"
@implementation Student
/**
* 构造方法
* 目的:给成员变量赋值(NSMutableArray作为成员变量,在init中,通过开辟内存空间完成的赋值)
*/
- (Student *)init {
if (self = [super init]) {
_array = [[NSMutableArray alloc] init];
}
return self;
}
/**
* 析构方法
* 目的:对成员变量释放
*/
- (void)dealloc {
//成员变量释放书写的位置
[_array release];
[super dealloc];
}
@end
6.Property修饰符
①新建Engine类
Engine.h
#import <Foundation/Foundation.h>
@interface Engine : NSObject
@end
Engline.m
#import "Engine.h"
@implementation Engine
@end
②新建Car类
Car.h
#import <Foundation/Foundation.h>
#import "Engine.h"
@interface Car : NSObject
@property (nonatomic, retain) Engine * engine;
@property (nonatomic, copy) NSString * name;
@property (nonatomic, assign) float price;
@end
Car.m
#import "Car.h"
@implementation Car
//retain
- (void)setEngine:(Engine *)engine {
//新值和旧值不相等再释放旧值retain新值
if (_engine != engine) {
//先释放旧值
[_engine release];
//修饰符的作用,给计数器+1,避免的问题:engine和_engin两者互不影响
_engine = [engine retain];
}
}
//copy
- (void)setName:(NSString *)name {
if (_name != name) {
[_name release];
_name = [name copy];
}
}
//assign
- (void)setPrice:(float)price {
_price = price;
}
- (void)dealloc {
self.engine = nil; //避免野指针
self.name = nil;
[super dealloc];
}
@end
③main.m
#import <Foundation/Foundation.h>
#import "Car.h"
#import "Engine.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Engine * engine = [[Engine alloc] init];
Car * car = [[Car alloc] init];
[car setEngine:engine];
[engine release];
[car release];
}
return 0;
}
【注意】在实际开发中如果是新项目我们一般选择ARC(自动内存管理)模式下开发,新开发的项目几乎不会用到MRC模式进行开发;如果有幸我们进入了一二线公司,BAT,京东,360等公司,项目系统庞大,可能涉及ARC和MRC(手动内存管理)混合开发。
开启ARC和MRC混编:Targets –> Build Phases –> Compile Sources选中将要使用MRC编辑的.m文件,输入-fno-objc-arc即可
7.autorelease(自动释放池)
①新建Student类
Student.h
#import <Foundation/Foundation.h>
@interface Student : NSObject
@end
Student.m
#import "Student.h"
@implementation Student
@end
②main.m
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
Student * stu;
@autoreleasepool {
stu = [[Student alloc] init];
[stu retain];
//autorelease会在@autoreleasepool右括号释放
[stu autorelease];
}
return 0;
}
写在结尾的话:
到今天为止,自学iOS开发系列更新了C和OC的内容,共计17篇技术博客。内容都是比较基础和浅显的,而且每篇博客都是以实践为主以理论为辅,可能是个人喜好吧,我推崇的学习方法是在实践中去掌握理论知识。有好多知识比较深奥,不适合初学者目前接触,现在写出来,反而容易造成学习者的迷惑。像protocol,delegate,block,内存管理这些知识,会在后面的章节中进一步讲解。
另外说点题外话,目前的iOS市场行情虽然确实出现了一点下行趋势,很多人对iOS的前景保持悲观状态,但是我认为iOS从业者不用这么悲观。iOS的市场其实远没有达到饱和状态,网上很多人抱怨iOS找工作不如去年和前年了,这种抱怨也是没有多大道理的。苹果7的销售依然火爆,闭环的苹果市场和百花齐放但是有些杂乱的安卓市场比较起来,还是有很多的优势。现在的市场不能说不好了,只能说要求高了,不再是低门槛进入了。它需要的是吸纳更多技术优良的人才,淘汰掉滥竽充数的人。
好了,文章的最好,让我们开心的迎接圣诞、元旦和自学iOS开发系列—-UI的到来。