iOS官方文档阅读记录

2018-06-29  本文已影响28人  xymspace

从7.1日开始

重点学习 :

---- 16天 --- 结束时间 : 7.17

(runtime非常核心.围绕runtime,系统方法加载顺序,编程中常见方法3个点,串联本章相关知识,最后2天时间梳理)

  1. NSObject

    • 系统自主调用的方法 (可重写,重写super调用方法实现父类调用):

      initialize
      load
      dealloc
      description

    • 常用方法 :

    • copymutableCopy
         可变对象发送此消息 : copy 与 mutableCopy 都可生成新对象.
         copy生成的是不可变对象, mutableCopy生成可变对象.
         生成的只是一个新的容器,容器内容未开辟新的空间.
    
深拷贝与浅拷贝.png
  > - `isKindOfClass` 与`isSubclassOfClass`
        
        用于判断当前类的所属,方便下一步编程使用
(KVC与KVO!

是runtime的具体应用)
>- 是oc的底层,基本通过 C 和汇编写 ,使c语言扩展出面向对象的功能.编译器会将 OC 代码转换成运行时代码,在运行时确定数据结构和函数.

  • 方法的调用本质 : 对象发送消息.

与runtime 匹配的消息机制 :


// performSelector最多携带2个参数
performSelector : withObject : afterDelay :
performSelector : withObject : afterDelay : inModes :
performSelectorOnMainThread :  withObject : waitUntilDone :
performSelectorOnMainThread :  withObject : waitUntilDone : modes :
performSelector : OnThread :  withObject : waitUntilDone :
performSelector : OnThread :  withObject : waitUntilDone : modes :
forwoardingTargetForSelector :
resolveClassMethod :
doesNotRecognizeSelector :
classFallbacksForKeyedArchiver :
#import <objc/message.h> 
或者直接导入
#import <objc/runtime.h>

实际应用 :
1. 获取某各类中所有的方法
2. 获取某个类中所有的属性
3. method swizzling (黑魔法)
如果类别中对系统方法进行method swizzling(方法交换),使用category中的load方法。
文档中说明了initialize和load的区别:
load是只要类所在文件被引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么 initialize也不会被调用.

需要清楚的几个runtime相关概念 :

  1. Method
    代表类中某个方法的类型
  2. Ivar
    是表示成员变量的类型。
    3.IMP
    一个函数指针,由编译器生成.当你发起一个 ObjC 消息之后,最终它会执行的那段代码,就是由这个函数指针指定.IMP 这个函数指针指向该方法的实现.

RunLoop相关联类(CoreFoundation)

CFRunLoopRef

CFRunLoopModeRef

CFRunLoopSourceRef

CFRunLoopTimerRef

 // 调用了scheduledTimer返回的定时器,已经自动被添加到当前runLoop中,而且是NSDefaultRunLoopMode
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];

 // 修改模式
 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

uCFRunLoopObserverRef

/**
* 顺序:
1、创建observer
2、添加观察者
3、释放observer
*/
 // 创建observer

//CFAllocatorGetDefault  默认值
//YES  表示重复监听

 CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {

 NSLog(@"----RunLoop状态发生改变---%zd", activity);

 });

 // 添加观察者:监听RunLoop的状态

//CFRunLoopGetCurrent()  表示要监听的RunLoop -- 这里是当前RunLoop

 CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);

 // 释放Observer
 CFRelease(observer);
 kCFRunLoopEntry = (1UL << 0),// 即将进入Loop

 kCFRunLoopBeforeTimers = (1UL << 1),//即将处理Timer

 kCFRunLoopBeforeSources = (1UL << 2),//即将处理Source

 kCFRunLoopBeforeWaiting = (1UL << 5),//刚进入休眠

 kCFRunLoopAfterWaiting = (1UL << 6),//刚从休眠中唤醒

 kCFRunLoopExit = (1UL << 7),//即将退出Loop

 kCFRunLoopAllActivities //所有活动状态

RunLoop应用场景

  1. 开启一个常驻线程(让一个子线程不进入消亡状态,等待其它线程发来消息,处理其它事件)
  2. 在子线程开一一个定时器
  3. 在子线程中进行一些长期监控(沙河监控、连网监控等)
  4. 可以控制定时器在特定模式下执行
  5. 可以让某些事件(任务、行为)在特定模式下执行
  6. 可以添加Observer 监听RunLoop的状态。如监听点击事件的处理(在所有点击事件之前做一些事情)

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html


作用1例:

//定义一个变量(未增加关键字static)

 int test = 1;

//因此,下面段引用代码,可以写在当前工程任意地方

 extern int text;

 text = 2;
作用2例:
int test = 1;

static int text = 1;
/**const修饰谁,谁就不可变*/
const NSInteger age = 5;
/**
* oc语法下,外界访问的是name,所以const修饰name
*/
NSString *const name = @"Jim";

// 下面这句代码const修饰的是*name
// const NSString *name = @"Jim";
引用关键字

引用全局变量:extern 类型名 变量名
引用全局常量:extern const 类型名 变量名
const + static 与 extern 可以组合使用,将const和static修饰的全局常量放在一个空的.m文件中,然后在头文件中使用extern关键字对这些全局常量进行引用,使用这些常量时,只需要导入头文件。建议将头文件引用的.m文件写相同名称,方便管理.

(其它不常用知识稍后再做汇总)

---- 30天 --- 结束时间 : 8.16
近来接触最为频繁的知识点 :

同一个View在同一个父控件上添加n次,等于添加一次,因为这个View占有的内存一直是同一份

视图消失

(知识点琐碎,最后2天时间梳理)


---- NotificationCenter ---- 5天 --- 结束时间 : 8.21
---- CFNetwork ---- 10天 --- 结束时间 : 8.30

上一篇 下一篇

猜你喜欢

热点阅读