OC深入知识点

  这两个月看了些OC底层一点的东西,还是有很多不明白的,为了加深印象,记录如下:

1、对象A的引用计数值存储于一张全局散列表中(未考虑tagged pointer优化),以A的地址&A为key,引用计数值减1为value。当A进行retain时,在全局散列表中根据&A找到对应的引用计数值,将其加1。

2、__weak修饰的所有对象存储于一张全局散列表中,例如A对象,若有__weak obj1 = A; __weak obj2 = A,则散列表中用&A为键,以一个类似数组的对象为value,该数组对象中存储了obj1和obj2。当A对象销毁时,到散列表中以&A为值找到对应数组,取出其中的obj1和obj2,将其指针清空为nil。

3、__weak修饰符只持有对象的弱引用,当在访问弱引用对象过程中,该对象有可能被废弃,存在危险。故当我们访问__weak修饰的对象时,系统会自动将其注册到autorelease中,保证我们在使用过程中该对象的生命周期。每一次访问弱引用对象都会将该对象注册进自动释放池一次,浪费性能。故现在流行如下写法。一来保证block执行过程中对象一定存在,二来不再访问重复访问弱引用修饰的对象,避免重复注册该对象到自动释放池。

 1     NSObject *obj = [NSObject new];
 3     __weak typeof(obj) weakObj = obj;
 5     void (^blk)() = ^{
 7         __strong typeof(weakObj) strongObj = obj;
 9         if (strongObj) {
10             NSLog(@"%@",strongObj);
11         }
12     };
14     blk();

4、代码片段

{
      id obj = [NSMutableArray array];
}

  上面用编译器模拟runtime代码可转换为如下: 

    id obj = objc_msgSend(NSMutableArray,@selector(array));
    objc_retainAutoreleasedReturnValue(obj);
    obj_release(obj)

  解读:对数组类NSMutableArray发送@selector(array)消息创建对象obj,retain对象让其存活,退出作用域销毁

    而类方法+(id)array的实现则为

+ (id)array{
    return [[NSMutableArray alloc] init];
}

  模拟转换如下

+ (id)array{
    id obj = objc_msgSend(NSMutableArray,@selector(array));
    objc_msgSend(obj,@selector(init));
    return objc_autoreleaseReturnValue(obj);
}

  解读:创建数组对象obj,将其放到自动释放池中后返回

  纵观上面解析,发现数组对象创建后放到自动释放池中,然后retain,此时引用计数值为2。退出作用域强引用指针obj释放,则引用计数器减一。当此次runloop结束后自动释放池清空,数组对象再次release,引用计数器为0数组销毁。从代码上来看,该数组放入自动释放池跟retain完全没有必要,生成对象直接强指针持有,退出作用域销毁即可。

  以下objc_autoreleaseReturnValue(): 用符号A代替、 objc_retainAutoreleasedReturnValue(): 用符号B代替

  runtime优化:A和B总是成对出现,A总在B之前。对方法A和B进行了特殊处理,让其在如上情况下不是将对象放入自动释放池和将对象retain,而是动态判断,当发现A方法后紧随着B方法,则A方法不再将对象放入自动释放池,而是将一个标记为flag设置为YES。对B方法,检查标志位flag,若发现其位YES,则不再将对象retain,而只是将标记为flag重置为NO,省去两次操作。伪代码如下:

 1 static BOOL flag = NO;
 2 id objc_autoreleaseReturnValue(obj){
 3     if (@"后面紧跟着B方法") {
 4         flag = YES;
 5     }else{
 6         [obj autorelease];
 7     }
 8     return obj;
 9 }
10
11 void objc_retainAutoreleasedReturnValue(obj){
12     if (flag) {
13         flag = NO;
14     }else{
15         [obj retain];
16     }
17 }

5、runtime一般用途

  a、数据绑定,主要函数objc_setAssociatedObject和objc_getAssociatedObject,主要用于分类属性扩充

  b、查看系统类的私有成员变量已经私有方法,可以针对系统私有变量进行KVC赋值。

  c、黑盒方法method swizzling,跟换系统方法实现,比如在所有控制器的viewWillAppear和viewDidDisappear方法中添加友盟统计方法,统计页面停留时间

6、KVO实现原理:观察A对象的progress属性,系统动态创建A的子类B,将A的isa指针指向B,重写对象B的setProgress方法,在里面发出如下通知,通知观察者的相应方法

- (void)setPregress: (CGFloat )progress{
    [self willChangeValueForKey:@"progress"];
    _progress = progress;
    [self didChangeValueForKey:@"progress"];
}

7、同步线程死锁。如下代码在主线程执行会死锁

    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"会死锁");
    });
  同步函数dispatch_sync在block返回之前会一直卡住线程。若当前代码在主线程执行,则主线程在block返回之前一直会是堵塞状态。而block恰好是在主线程执行,而主线程被堵塞,于是blcok不会执行,block不会执行则不会返回,于是主线程一直堵塞。造成死锁。
时间: 2024-08-25 23:08:34

OC深入知识点的相关文章

iOS开发——动画OC篇&知识点总结

图层与动画知识点总结 1.Core Animation 非娱乐类的软件都会用到的动画,操作简单. 2.Quartz 2D绘图 是一个2D绘图引擎. (1) 绘图Context是一个绘图的目标对象,定义了绘图的基本属性,如颜色.绘图范围.线宽及样式等. (2)通过UIView会创建Context,可以用类似如下的语句来得到当前的Context. CGContextRef currentContext = UIGraphicsGetCurrentContext(); (3)如果在对其进行修改前想要保

OC面向对象和小知识点

oc小知识点: 在c语言中汉子占三个字节 oc中汉子和字符都是一个字节 #include 和 #import 区别w import 可以防止重复包含 Foundation 把oc的库文件都包含过来 @autoreleasepool 自动释放池 NSLog 会自动换行 NSLog 会自动输出时间项目信息 NSLog 传递的函数参数是NSString对象 printf传递的是字符串常量指针 NSLog 也可以进行格式化输出 NSlog(@"------>%s", str); //不可

IOS阶段学习第17天笔记(OC中文件的操作)

IOS学习(OC语言)知识点整理 一.单例模式 1)单例是一种编程思想,一个设计模式,与语言无关在采用了单例对象的应用程序中,需要单例类自行提供实例化单例对象, 不管实例化单例对象多少次,只有一个对象存在,这个对象是全局的,能够被整个应用程序共享,访问 2)使用单例模式时使用类提供的类方法获取单例对象,尽量不要用alloc init的方法获取单例对象 3)单例类提供类方法获取单例对象时类方法一般以sharedXX/standedXX/defaultXX开头 实例代码: #import "Plan

object-c所有知识点集合

// //  main.m //  OC所有知识点集合 // //  Created by apple on 15/11/24. //  Copyright © 2015年 apple. All rights reserved. // #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { //1.字符串 //1.字符串的截取(三个位置的截取) NSString

IOS阶段学习第20天笔记(OC中的内存管理)

IOS学习(OC语言)知识点整理 一.OC中的内存管理 1)概念:内存管理的对象为所有继承了NSObject的对象,对基本数据(如:int .float.double...)无效      OC中采用引用计数器对内存做管理,他是一个整数数据,表示对象引用的次数,每个对象分配4字节      的内存空间存放引用计数器.当一个对象的引用计数器为0时 它将被自动释放,反过来说 当使用alloc.      new .copy(mutableCopy)创建新对象时,引用计数器默认为1 2)黄金法则 当使

IOS 阶段学习第24天笔记(Block的介绍)

IOS学习(OC语言)知识点整理 一.Block 的介绍 1)概念: block 是一种数据类型,类似于C语言中没有名字的函数,可以接收参数,也可以返回值与C函数一样被调用 封装一段代码 可以在任何地方调用 block 也可以作为函数参数,以及函数返回值 2)Block 实例代码 1 //定义了一个block类型MyBlock,MyBlock类型的变量只能指向带两个int的参数和返回int的代码块 2 typedef int (^MyBlock)(int,int); 3 //定义一个函数指针 4

IOS 阶段学习第25天笔记(IOS沙盒机制介绍)

IOS学习(OC语言)知识点整理 一.IOS沙盒机制介绍 1)概念:每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用放入文件 系统隔离,ios系统不允许访问 其他应用的应用沙盒,但在ios8中已经开放访问(extension) 2)extension是ios8新开放的一种对几个固定系统区域的拓展机制,它可以在一定程度上弥补ios的沙盒机制对应用间的通信限制 3)应用沙盒一般包括以下几个文件目录: 1.应用程序包:包含所有资源文件和可执行文件 2.Documents:保存应用

IOS 阶段学习第22天笔记(JSON数据格式)

IOS学习(OC语言)知识点整理 一.JSON数据格式 1)概念:json是一种网络数据传输格式,有值/对象:{“A”:1,”B”:”2”…}词典:对象的序列:[,,,,,]数组两种数据类型 2)URLWithString 将字符串网址封装成NSURL对象 例如: 1 NSString *urlStr=@"http://10.0.8.8/sns/my/user_list.php?number=20 2 &page=";//get post 3 NSURL *url=[NSURL

IOS阶段学习第13天笔记(NSString与NSMutableString)

IOS学习(OC语言)知识点整理 一.OC字符串的操作 1)OC中字符串分为两种: 1.不可变字符串NSString:不能修改对象内容,但是可以改变对象的指针. 2.可变字符串NSMutableString:可以修改对象内容. 二.NSString 不可变字符串的操作 1)将字符串常量对象直接赋值给字符串引用 NSString *[email protected]"hello"; 字符串对象的输出格式:NSLog(@"str1=%@",str1). 2)initWi