自我学习--内存管理

1.堆空间里的内存是系统自己管理与回收,栈区的数据一般不用自己去管,系统会自动回收

1>每个OC对象内部有4个字节的存储空间来存储引用计数器

2>main函数有一个循环

3>retain 调用返回对象本身

4>野指针和空指针:指向不可用内存的指针的指针是野指针

5>EXC_BAD_ACCESS:访问了一块坏的内存(已经被回收,已经不可用的内存)

p = nil :清空指针

OC中不存在空指针操作


原则:

1>你想使用某个对象,就应该让计数器(对象+1)(让对象做一次retain操作)

2>你不想在使用(占用)某个对象,就应该让对象的计数器-1(让对象做一次release)

3>谁retain,谁release

4>谁alloc,谁release


内存管理代码规范:

1>只要调用了alloc,必须release(aoturelease)

2>如果对象不是通过alloc创建的,就不必须要有release


set方法的代码规范

1>基本数据类型:直接复制

- (void)setAge:(int)age

{

_age = age;

}

2>OC对象类型

-(void)setCar:(Car *)car

{

1.先判断是不是新传进来对象

if (car!=_car)

{

2.//对旧的对象做一次release

[_car release];

3.//对新对象做一次retain

[car retain];

}

}


dealloc方法的代码规范

1>一定要[super dealloc],而且放到最后面

2>对self(当前)所有的其他对象做一次release

-(void)dealloc{

[_car release];

[super dealloc];

}


基本数据类型是不需要管理内存的


retain:生成的set方法里面,release旧值,retain新值


Property参数:

1.内存管理相关的参数

*retain:release旧值,retain新值

*assign:

*copy:

2.是否要生成set方法

3.多线程管理

4.sette和getter方法的名称


@class的作用:仅仅告诉 编译器,声明一个类,类里的东西不知道


开发中引用一个类的规范:

1>在.h文件中用@class来声明类

2>在.m文件中用#import来包含类的所有东西


两端循环引用解决方案:

1>一端用retain----strong

2>一端用assign---weak


@class和import的区别:

#import方式会包含被引用类的所有信息,包含被引用类的变量和方法,@class方式只是告诉编译器在A.h文件中B *b只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息

如果有上百个头文件都#Import 了同一个文件,或者这些文件一次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来讲,使用@class方式就不会出现这种问题了。

在.m实现文件中,如果需要引用到被引用类的实例变量或者方法时,还需要使用#import方式引入被引用类.


aoturelease:半自动释放,不会改变对象的引用计数器

1>aoturelease方法会返回对象本身


基本用法:

1>会将对象放到一个自动释放池中

2>当自动释放池被销毁时,会对池子里面的所有对象做一次release操作

3>会返回对象本身

4>调用完autorelease方法后,对象的计数器不变


好处:

1>不用再关心对象释放的时间

2>不用再关心什么时候调用release


autorelease使用注意:

1>占用内存较大的对象不要随便使用autorelease

2>占用内存较小的对象使用autorelease,没有太大影响


错误写法:

1>alloc之后调用了autorelease,又调用release

2>连续多次调用autorelease  


自动释放池

1>在ios程序运行过程中,会创建无数个池子,这些池子都是以栈结构存在(先进后出)

2>当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池


1、系统自带的方法里面没有包含alloc/new/copy,说明返回的对象都是aoturelease的

2、开发中经常会提供一些类方法,快速创建一个已经aoturelease过的对象

1>创建对象时不要直接用类名,一般用self


总结:dealoc不要直接调用,这个一般要系统自己调用


ARC:

1.ARC是编译器特性:有alloc,就会自动在合适的地方插入release,进行内存管理

2.ARC判断准则

1>只要没有强指针指向对象,就会释放对象

2>指针分两种:没有强指针指向的对象,会马上释放

强指针:默认情况下是所有指针都是强指针__strong

弱指针:弱指针是不能决定对象要不要释放。只要弱指针指向对象不存在,就会直接销毁对象。__weak

当弱指针指向的对象被销毁时,指针会自动被置为nil


ARC特点:

1>不允许调用release.retain,retainCount

2>允许重写dealloc,但是不允许调用[super dealloc]

3>property的参数

*strong:成员变量是强指针(适用于OC对象类型)

*weak:成员变量是弱指针(适用于OC对象)

*assign:适用于非OC对象类型

4>以前的retain,改为strong


MRC 与 ARC 互转:

-fno-objc-arc,不使用ARC

-f-objc-arc,使用ARC


两端循环引用的时候,解决方案:

1>ARC

1端用strong,另一端用weak

2>非ARC

1端用retain,另一端用assign


OC程序完全兼容C语言

NSLog输出内容会自动换行


#include 与 import对比

1>import的用途:

1.跟include用途一样,拷贝文件内容

2.可以自动防止文件的内容被重复拷贝

2>include:会重复拷贝内容


NSObjcRuntime.h 中有NSLog函数的声明


包含主头文件就可以使用这个框架的东西


运行过程:

1>编写OC源文件:.m、.c

2>编译:cc -c xxx.m xxx.c

3>链接:cc xxx.o xxx.o -framework Foundation

(只有用到了Foundation框架才需要加上 -framework Founfation)

4>运行:./a.out

链接应该是将所有的可执行文件+函数库联系在一起,生成一个可执行文件


主头文件:

1>主头文件:最主要的头文件,名字一般跟框架名称一样,包含了框架中的所有其他文件

2>Foundation框架的主头文件名称就是Foundation.h

3>只需要包含Foundation框架主头文件,就可以使用整个框架的东西


思想

1.面向对象和面向过程的区别

常用术语:

1>面向过程:Procedure Oriented

2>面向对象:Object Oriented,简称OO.解决问题的核心就是对象

3>面向对象过程:Object Oriented Programming,简称 OOP


类与对象

类是抽象的,对所有相同属性的一个概括

类就相当于是图纸 — 制作汽车架构的图纸

对象是类的具体存在


开发步骤:

1>先分析项目中需要什么,再设计相应的类:类中包括属性和相应的行为


类的设计只关心三件事

1>事物名称(类名):人

2>属性:age,name

3>行为:eat,run


set方法:

1.作用:提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤

2.命名规范:

1>方法名必须以set开头

2>set后面跟上成员变量的名称,成员变量的首字母必须大写

3>返回值一定是void

4>一定要接收一个参数,而且参数类型跟成员变量类型 一致

5>形参的名称不能跟成员变量名一样


get方法:

1.作用是返回对象内部的成员变量

2.命名规范:

1>肯定有返回值,返回值类型肯定与成员变量类型一致

2>方法名跟成员变量名一样

3>不需要接收任何参数


面向对象三大特性

成员变量的封装,继承,多态

封装好处

1.把不想被别人了解的代码细节封装起来,为了保证代码的安全性


类方法与对象方法 的区别:

类方法只能用类来调用

1>对象方法

1.减号 -开头

2.只能由对象来调用

3.对象方法中能访问当前对象的成员变量


2>类方法

1.加号 +开头

2.只能由类来调用

3.类方法中不可访问成员变量


类方法的好处与使用场合

1>不依赖与对象,执行效率高

2>能用类方法尽量使用类方法

3>场合:当方法内部不需要使用成员变量时,就可以改为类方法


可以允许类方法和对象方法同名


继承的好处

1>抽取重复代码

2>建立了类之间的关系

子类可以拥有父类的所有的成员变量和方法

注意点

1>基本上所有的根类是NSObject

2>OC中不允许子类和父类有相同的成员变量

3>调用某个方法时,优先在类中找,找不到再去父类中找


重写:子类重写实现父类的某个方法,就是覆盖掉父类以前的方法


集成耦合性太强


继承的使用场合:

1>当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中。

2>当A类中拥有B类中的部分属性和方法时,可以考虑让B类继承A类


继承与组合:

继承:xx是xx

组合:xxx拥有xxx,当继承不合理的时候,通过组合也可以拥有继承的功能


super的作用

1>直接调用父类中的某一个方法

2>如果super处在对象方法中,那么就调用父类的对象方法

如果处在类方法中,那就调用父类的类方法


super使用场景:子类重写父类的方法时想保留父类的一些行为


多态:多种形态,父类指针指向子类对象

1>想实现多态就必须有继承


多态的好处:

1>可以将多个方法整合成一个函数

2>可以用一个父类类型指向多个多个对象


多态的局限性:

1>父类类型的变量,不能用来调用子类的方法。如果想要调用子类的方法,必须要进行相应类型的强转

2>通过强制转换


多态:

1>没有继承就没有多态

2>代码的体现:父类类型的指针指向子类对象

3>好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象


init方法:

构造方法:用来初始化对象的方法,是个对象方法,-开头

重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值

重写构造方法的注意点:

1.先调用父类的构造方法[super init]

2.再进行子类内部成员变量的初始化


+load(当加载类到内存中的时候,开始调用)

+initial(当第一次使用这个类的时候开始调用)


类也是类对象[NSObject class];[p class]


_cmd代表当前方法


SEL其实就是对方法一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法。


description

有-方法和+方法

-方法,描述实例的属性

+方法,描述类的属性





你可能感兴趣的:(自我学习--内存管理)