-
#import
就相当于#include
,但是是#include
的升级版,#import
能防止重复包含
@class
仅仅是声明一个类名,并不会包含类的完整声明;@class
还能解决循环包含的问题 - 什么是类:具有相同特征和行为的事物的抽象
什么是对象:万物皆对象 某一个类的具体事物 - 面向对象的三大特点:继承,多态,封装
- 继承:父类(超类)
superclass
, 子类subclass
- 子类能继承父类全部的特征和行为,继承是单向的,不能相互继承
- 继承具有传递性:当你设想的两个类,具有相同的特征和行为的时候使用继承,把公共的方法和实例变量写在父类里,子类只需要写自己独有的实例变量和方法即可
特点:oc
中只允许单继承,一个子类只有一个父类
没有父类的类称为根类,oc
中的根类是NSObject
继承:可以继承全部的实例变量和方法
子类中不能有和父类相同的实例变量,但是可以有同名的方法(重写overwrite
)
继承体系的方法或者实例变量的查找:在自己类中找,如果没有,去父类中找,如果父类中没有,就去父类的父类中,如果父类的父类也没有,就还往上找,直到找到基类(NSObject
),如果(NSObject
)也没有就报错了
- 多态:不同对象响应同一方法的不同表现
- 继承:父类(超类)
-
super
是一条编译器指令,作用是给父类发送消息,可以执行父类中的方法 -
categery
类目或分类,作用是为类添加方法 注意:类目只能添加方法
通过category
添加的方法会成为原类的一部分,达到扩展一个类的目的
category
和子类的区别:category
只能添加方法,子类既可以添加方法也可以添加实例变量,category
添加的方法会成为原类的一部分,可以被继承,子类的添加可以子类有;使用原来的类就可以调用,使用子类来调用 -
extension
延展 主要作用:管理类的私有方法
私有方法:外界无法访问,只能在本类内部使用 - 协议
protocol
:协议是一套标准(一套方法的声明.h文件) - 代理(
delegate
):- 代理设计模式(
delegate
)设计模式:前辈们在软件开发过程中总结出来的经验 - 什么是代理:受委托方委托,代表当事人进行某种活动,如:诉讼,签订合同等
- 代理的作用:
- 1.当A类对象发生什么事想通知B类型对象(B类对象成为A类对象的代理)
- 2.A类中有些事情,自己无法处理,需要B类对象帮助其处理(B类对象成为A类对象的代理)
- 3.B类对象想知道A类对象中发生的事情,(B类对象成为A类对象的代理)
- 代理设计模式(
-
blcok
分为栈区blcok
堆区blcok
全局区block
当block
中使用到对象的时候,block
会对对象进行一次retain
操作 -
KVO
是键值监听,可以监听一个对象属性值的改变 -
kvc
:key-value-coding
(键值编码)间接的对实例变量进行取值或者赋值
携带key-value
键值映射关系 只有两种,一种是字典 一种是自定义对象
所有的东西都不再是私有的,因为即使是私有,采用kvc
也可以赋值.
eg:
Person *ppp=[[Person alloc]init];
//普通赋值
ppp.name = @"ppp";
//kvc赋值
[ppp setValue:@"aaa" forKey:@"name"];
//kvc取值
NSString *str=[ppp valueForKey:@"name"];
实现kvo
,被观察者的对象必须使用kvc
来修改实例变量,这样才能被观察者观察到,因此,kvc是kvo的基础或者说kvo的实现是建立在kvc的基础上的
-
常见的的设计模式:单例设计,代理设计,观察者(通知),工厂方法
-
readonly
只读,只生成getter
不生成setter
readwrite
可读可写默认,生成setter
和getter
atomic
原子性对setter
方法进行加锁操作,浪费资源(默认)
noatomic
非原子性 不进行加锁操作,性能更高
setter
自定义赋值方法的名字
getter
自定义取值方法的名字
assign
用于基本数据类型
copy retain
用于对象 -
内存管理
-
1.为什么要内存管理:移动设备的内存极其有限,每个app所能占用的内存是有限制的,当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要在使用的内存空间
-
2.管理范围:任何继承了
NSObject
的对象,也就是foundation
框架里的东西 -
3.内存从低到高分为 栈区 堆区 静态区 常量区 代码区
栈区: 存储局部变量,数组,指针,内存有系统分配,系统回收
堆区: 自己分配,自己回收malloc
(要开辟的空间数量,单位是字节)memorry alloc
内存分配free
(要释放的那块内存的指针)回收空间
静态区:全局变量和static
修饰的变量
常量区:存放常量(只读)
代码区:存放代码(只读) -
4.内存错误主要两方面:内存溢出:超出系统为每一个程序分配的空间
野指针:内存空间已经被回收,仍然使用指针操作这块内存 -
5.内存管理的方式:
垃圾回收(gc)garbage collection
:程序员只需要开辟空间,不需要用代码控制释放,系统来判断哪些空间不再使用,并回收这些内存空间
MRC Manual Reference Count:
手动引用计数:内存的开辟和释放都是有程序代码控制的,相比垃圾回收,内存控制灵活,可以在需要释放的时候及时释放
ARC Auto Reference Count:
自动引用计数:允许用户开辟空间,不去释放空间,本质还是MRC
,只是编译器帮助我们把释放的代码添加上了
ios
只支持ARC、MRC
两种 ,ARC
是基于MRC
的 -
6.MRC的内容
- 6.1怎么回收?
- a.每个
oc
的对象,都有自己的引用计数器,是一个整数,表示“对象被引用的次数”(也就是还有多少个指针指向对象),既有多少人正在使用这个oc
对象,每个oc
对象内部专门有4个字节的存储空间来存储引用计数器,所以操作计算器就能进行内存管理 - b.引用计数器的作用:当使用
alloc,new,copy
创建一个对象时,新对象的引用计数器默认就是1,当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收,换句话说,如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不能被回收,除非整个程序已经退出,程序退出后,操作系统会回收作为程序开辟的空间 - c.对引用计数器的操作:给对象发送一条
retain
消息,可以使引用计数器的值加1,给对象发送一条release
消息,可以使引用计数器的值减1,可以给对象发送retaincount
消息获得当前的引用计数器的值,但是他获得的消息根本不准
- a.每个
- 6.1怎么回收?
-
7.总结:
alloc new :
开辟空间,对象引用计数变为1,从无到有0->1
retain
引用计数加1,在原来的基础上加1
copy
把某一内存中的内容拷贝一份,拷贝的新的内存空间中,被拷贝的引用计数不变,新的引用计数为1
release
引用计数减1,在原来的基础上减一,若减1后引用计数为0,那么对象内存回收
autorelease:
实际上只是把对release
的调用延迟了,对于每一次的autorelease
,系统只是把该对象放入当前的autoreleasepool
中,当该pool
被释放时,该pool
中的所有对象会被调用release
-
8.对象销毁
当一个对象的引用计数器为0时,那么他将被销毁,其占用的内存被系统回收,当一个对象被销毁时,系统会自动向对象发送一条dealloc
消息,一般会重写dealloc
的方法,一旦重写了dealloc
方法,就要在最后写[super dealloc]
,
已经被回收的对象,称为僵尸对象
野指针:指向了不可用的内存(指向僵尸对象)
空指针:=nil
,指向无用区域,向空指针发送任何消息都不会报错 -
9.内存管理的黄金原则:如果对一个对象使用了
alloc,new,copy,retain
使引用计数增加,那么你必须使用相应的release
,或者autorelease
使引用计数减少,增加的等于减少的。
只要还有人用这个对象,那么这个对象就不会被回收,只要你想用这个对象,就应该让这个对象的引用计数器加1,你不想用这个对象,就应该让这个对象的引用计数器-1,曾经让对象的计数器加1,就必须在最后让对象计数器减1
release
旧值,retain
新值(用于oc
对象),assgin
直接赋值,不做任何内存管理(默认,用于非oc
)
copy:release
旧值,copy
新值(一般用于NSString
) -
10.@class作用:对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类可用
@class
,@class
只是告诉编译器在A.h文件中B*b
只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中的信息 -
11.循环
retain
:比如A对象retain
了B对象,B对象retain
了A 对象这样会导致A、B对象永远无法释放
解决方法 :一端使用assgin
代理用assgin
-
-
拷贝:想要调用
copy
和mutablecopy
两个方法,那么类就一定要实现对应的协议NSCoping
和NSMutableCopying
,遵守NSMutableCopying
,并且实现copywithzone
深拷贝(mutablecopy
):对象拷贝-直接拷贝内容,生成对象是可变字符串,会产生新对象
浅拷贝(copy
):指针拷贝-将指针中的地址值拷贝一份,对于不可变字符串,不会产生新对象 -
ARC:是自
ios5
之后增加的新特性,完全消除了手动管理内存的繁琐,编译器会自动在适当的地方插入适当的retain,release,autorelease
语句,编译器为你处理了一切
规则:只要还有一个强指针指向对象,对象就会保持在内存中,strong
默认所有实例变量和局部变量都是strong
指针
弱指针指向的对象被回收后,弱指针会自动变成nil指针,不会引发野指针错误
使用注意:不能调用release,retain,autorelease,retainCount
可以重写dealloc
但是不能调用[super dealloc]
@property:想长期拥有某个对象,应该用strong
,其他对象用weak
,其他基本数据类型依然用assgin
,两端互相引用时,一端用strong
,一端用weak
-
数据持久化
write to file
NSArray *array=@[@"12",@"34"];
NSString *path=@"/Users/zj/Desktop/text";
//拼接路径
NSString * path1=[path stringByAppendingPathComponent:@"array.txt"]; [array writeToFile:path1 atomically:YES];//写入文件
//把文件读出来,arrayWithContentsOfFile:具有文件内容的数组
NSArray *arr=[NSArray arrayWithContentsOfFile:path1];
注意:并不是所有的都可以
writeToFil
,NSString
,NSArray
,NSDictionary
,NSSet
,NSDate
都可以writeToFil
* 归档
调用
NSString *path=@"/Users/zj/Desktop/text/array.txt";
Person *p=[[Person alloc]init];
p.name=@"lala";
p.age=@"12";
//归档
BOOL i = [NSKeyedArchiver archiveRootObject:p toFile:path1];
if (i) {
NSLog(@"归档成功");
}else{
NSLog(@"归档失败");
}
//反归档(解档)
Person *p1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
NSLog(@"%@",p1.name);
类
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding>
//归档时需要遵守<NSCoding>协议
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *age;
@end
#import "Person.h"
@implementation Person
//归档
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_age forKey:@"age"];
}
//反归档
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self=[super init]) {
_name =[aDecoder decodeObjectForKey:@"name"];
}
return self;
}
@end
注意:对于自己创建的对象,只能归档反归档
- 沙盒机制:是一种安全的体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容,所有的非代码文件都保存在这个地方,比如图片,声音,属性列表和文本文件等
总的来说:- 1.每个应用程序都在自己的沙盒内
- 2.不能随意的跨越自己的沙盒去访问别的应用程序沙盒的内容
- 3.应用程序向外请求或接收数据都需要经过权限认证
- 4.沙盒中的各个文件夹
- 1.
Documents
:用来存放应用程序运行需要的数据,比如数据库等,iTunes备份时会备份此文件夹得内容,存放内容不易过大,太大了通不过申请 - 2.
Liabray
:包括caches
和prefrences
用来存放应用程序运行后产生的数据,应用程序退出并不会删除此文件夹内的内容,但是iTunes备份时也不会备份此文件夹得内容- 2.1
caches
存放应用程序的缓存文件 - 2.2
prefrences
存放应用程序的设置
- 2.1
- 3.
tmp
存放应用程序临时的数据,退出后内容会被删除
- 1.
- 线程和进程的区别?
一个应用程序对应一个进程,一个进程帮助程序占据一块存储空间
要想在进程中执行任务,就必须开启线程,一条线程就代表一个任务
一个进程中允许开启多条线程,也就是同时执行多个任务
网友评论