Objective-C基础笔记整理(一)基础篇与内存篇

  • 基础篇
    • 1、static、const、extern 关键字
    • 2、#import、#include、@class、import< >、import” “
    • 3、@interface与@property
    • 4、属性关键字 strong、weak、assign、retain、copy、readwrite、readonly、automic、nonatomic
    • 5、self与super的区别
    • 6、深拷贝与浅拷贝
    • 7、KVC与KVO
    • 8、Notification与KVO的不同
    • 9、对单例的理解
    • 10、类目、延展、协议
    • 11、tableView的重用机制
    • 12、程序的生命周期 (viewcontroller)类
    • 13、界面传值的几种方式
  • 内存篇
    • 1、内存分配五大区
    • 2、对内存管理的理解
    • 3、索引计数
    • 4、ARC机制与其实现原理
    • 5、内存管理的几条原则
    • 6、ARC与非ARC的混合

基础篇

1、static、const、extern 关键字

static:定义静态变量,声明局部变量时,编译时就为其分配内存,程序退出时才会释放。声明全局变量时,作用域只限于当前文件,其它类文件是访问不到的。
const:定义不可改变的常量值,相对于宏来讲,宏只是替换的,不会报编译错误,而 const会编译检查,会报编译错误。大量使用宏会造成编译缓慢,因为每次都需要替换,所以苹果推荐我们使用const常量。
extern:获取全局变量的值,不能用于定义变量。工作原理 - 先在当前文件需要全局变量,如果没有找到,才会到其它文件寻找。

使用场景

static与const的联合使用,声明一个静态的全局变量,例如可以替代宏,把一个经常使用的字符转常量,定义成一个全局的静态只读常量。

static NSString * const key = @"name";

extern与const联合使用,定义全局变量,FOUNDATION_EXTERN 是 extern 的宏定义。

.m文件
NSString * const KEYNAME = @"name";

.h文件
FOUNDATION_EXTERN NSString * const KEYNAME;

2、#import、#include、@class、import< >、import” “

  • #import:防止重复编译,交叉引用。
  • #include:重复编译头文件。
  • @class:告诉编译器有这么一个类。
  • import< >:导入的是系统的文件。
  • import” “:导入的是自定义的文件。

3、@interface与@property

@interface 常用的三种:声明类(Class)、声明类别(Category)、声明扩展(Extension)。

声明类
@interface Dog : NSObject

@end

声明类别
@interface Dog(类别名)

@end

声明扩展
@interface Dog ()

@end

property 关键字自动生成某个成员变量的setter与getter方法

@property (nonatomic, strong) NSString *name;

自动生成

- (void)setName:(NSString *)name {
    _name = name;
}

- (NSString *)name {
    return _name;
}

4、属性关键字 strong、weak、assign、retain、copy、readwrite、readonly、automic、nonatomic

  • automic:默认的,保证在多线程的情况下,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题,一般用不到,因为会影响性能。
  • nonatomic:非原子操作,不提供多线程保护,非线程同步,一般都用这个。
  • assign:修饰基本的数据类型。
  • strong:一般用于对象类型,保留新值,释放旧值,然后再将新值设置上去,主要用于修饰强引用的属性。
  • weak:既不保留新值,也不释放旧值,在属性对象释放时,属性值也会清空,主要用于修饰弱引用的属性,一般用于代理、UI控件等。
  • copy:用于希望获得原对象的副本而不改变原对象的内容(拷贝一个新的对象,原对象不变)。
  • readwrite:可读可写,但需要手动实现setter与gette方法。
  • readonly:只读,只生成getter方法。

5、self与super的区别

  • self是调用自己的方法,而super是调用父类的方法。
  • 使用self调用方法时会从当前类的方法列表中去寻找,若没有则会去父类中去寻找。而super则从父类中去寻找,调用父类的方法。

6、深拷贝与浅拷贝

  • 浅拷贝只是复制了对象的指针,和原对象一样指向同一个地址。
  • 深拷贝复制对象引用本身,指向的是一个新地址。
  • 要想实现自定义对象的拷贝,必须实现NSCopying或是NSMutableCopying协议,实现该协议的copyWithZone方法和mutableCopyWithZone方法,深拷贝和浅拷贝的区别就在于copyWithZone方法的实现。

7、KVC与KVO

  • KVC:键值编码 -> 通过指定的要访问属性的名字的字符串标识符,可以进行类的属性读取和设置。
  • KVO:键值观察 -> 注册一个对象的观察者,当该对象的某个属性变化时能够接受到通知。

8、Notification与KVO的不同

  • Notification:需要被观察者主动发出通知,然后观察者注册监听后再进行操作。
  • KVO:被观察者不需要添加任何代码,所以谁监听谁注册,然后对响应事件进行处理。

9、对单例的理解

  • 单例的生命周期和程序的生命周期相同,仅能生成一次且不能被销毁的唯一实例
  • 一个特定的类中仅有一个实例对象
  • 单例可以在程序的任何位置被访问
  • 创建时使用静态变量保证单例对象始终存在
+ (Single *)shareInstance {
    static Single *single = nil;
    if (!single) {
        single = [[Single alloc] init];
    }
    return single;
}

10、类目、延展、协议

类目(分类):指向已知的类,增加新的方法,不会破坏封装性。类目具有更高的优先级,如果跟原有的类冲突,将会覆盖原来的方法。
延展(类扩展):为一个类添加一些私有的成员变量和方法。
协议:声明一个方法,让别的类来实现,协议不是类,它是定义一个其他对象可以实现的接口。

11、tableView的重用机制

UITableView通过重用单元格的方式来达到节省内存的目的。通过为每个单元格指定一个重用标识符(reuseIdentifier),指定了单元格的种类。假如一个TableView有10个单元格,但是屏幕上最多只能显示4个,实际上系统只为其分配了4个单元格的内存,当滚动单元格时,屏幕内显示的单元格会重复使用这四个内存。简单理解就是单元格滑出屏幕时,就会将其放到一个重用池(数组)中,当要显示某一行单元格时,再将其取出来,如果没有,就直接创建。

12、程序的生命周期 (viewcontroller)类

- (void)loadView 加载视图,只调用一次。
- (void)viewDidLoad  视图加载完成,一般在这个方法中初始化用户界面,只调用一次
- (void)viewWillAppear:(BOOL)animated 视图将要显示,视图将要出现的时候调用。
- (void)viewDidAppear:(BOOL)animated 视图已经显示,视图出现的时候调用 。
- (void)viewWillDisappear:(BOOL)animated 视图将要消失,视图将要消失的时候调用。
- (void)viewDidDisappear:(BOOL)animated 视图已经消失,视图消失的时候调用

13、界面传值的几种方式

属性传值:一般从主页传到详情页。
init传值:需在详情页声明init方法。
Block传值:详情页传值到主页,block一般用于回调,传值需在详情页声明block类型,属性与传值方法。
协议传值(代理传值):在详情页声明协议,设置代理属性。
通知传值:多界面传值,适用于任意控制器。(NSNotificationCenter)。
单例传值:单例贯穿整个应用程序声明周期,利用单例传值适用于任何控制器,使用前提是在获取值的时候必须保证单例属性有值,否则获取值为nil。

内存篇

1、内存分配五大区

栈区:由编译器自动分配内存并释放
堆区:由开发者自己分配内存并释放
全局区(静态区):存储全局变量和静态变量
文字常量区:存放常量字符串,程序结束后由系统释放
代码区:存放函数体的二进制代码

2、对内存管理的理解

  • OC中有三种内存管理方式:ARC(自动计数)、MRC(手动计数)、自动释放池。
  • 当使用new、alloc、或是copy创建一个对象时,该对象引用计数器为1,如果不需要使用该对象时,可以向其发送release或autorelease消息,在使用完毕后进行销毁。如果retain了某个对象,需要release或autorelease该对象,保持retain和release方法的使用次数相等。
  • 使用new、alloc、copy关键字生成的对象和retain了的对象需要手动释放,设置为autorelease的对象不需要手动释放,因为其会直接进入自动释放池。使用便利构造方法的对象也无需手动管理内存。

3、索引计数

创建一个对象后,索引计数就表示有多少个变量在使用这个对象,当索引计数为0时,就表示这个对象没人用了,就可以清除了,但有人使用,做了标记,却在不用的时候没有取消自己的索引计数,那么这块资源就永远被标记有人在用,无法释放,即内存泄漏。

4、ARC机制与其实现原理

  • ARC就是在代码中自动加入retain/release,原先需要手动添加用来处理内存管理的引用计数的代码,可以自动的由编译器来执行。
  • ARC并不是GC(垃圾回收机制),它只是一种代码静态分析工具,都是释放不需要的内存空间,不同的是ARC在编译的时候会自动加入retain/release,而GC是在运行的时候专门处理的工具,当引用计数为0时,就会释放空间。

5、内存管理的几条原则

  • OC中内存管理机制中比较重要的一条规律是:谁申请,谁释放,要避免过早释放和内存泄漏。
  • 当new、alloc、或copy方法创建一个对象时,该对象的引用计数为1,如果不适用该对象时,应向其发送release或者autorelease消息,在使用完毕后 进行销毁。
  • 如果retain了某个对象,需要release或autorelease该对象,保持retain方法和release方法使用次数相等。
  • 通过方法获取对象,该对象引用计数加一,需要在使用完毕后进行release。

6、ARC与非ARC的混合

  • ARC项目引入非ARC文件,则标识 -fno-objc-arc
  • 非ARC项目引入ARC文件,则标识 -fobjc-arc

待补充

你可能感兴趣的:(Objective-C基础笔记)