美文网首页
Runtime知识点整理1

Runtime知识点整理1

作者: 化二缺 | 来源:发表于2020-05-15 09:54 被阅读0次
  • OC消息机制?
  • 消息转发机制流程?
  • 什么是Runtime?什么场景下使用?

==============巴拉巴拉...=================

  • OC是一门动态性比较强的编程语言,跟C 、C++ 等语言有着很大不同
  • OC的动态性是由Runtime API 来支持的
  • Runtime API 提供的接口基本都是C语言的,源码由C\C++\汇编语言编写

isa详解

  • 想要学习Runtime,首先要了解它的底层的一些常用的数据结构,比如isa指针
  • 在arm64架构之前,isa就是一个普通的指针,存储着Class,meta-Class对象的内存地址
  • 从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多信息


    union.png

!(5) == 0
!!(5) == 1

! image.png

swift 按位存储的尝试

//
//  YZPerson.swift
//  HYZExplore
//
//  Created by HYZ on 2020/5/18.
//  Copyright © 2020 HYZ. All rights reserved.
//

import UIKit


class YZPerson: NSObject {
    let YZTallMask = (1<<0)
    let YZRichMask = (1<<1)
    let YZHandsomeMask = (1<<2)
    
    var _tallRichHandsome = 0b00000000
    
    override init() {
        super.init()
        _tallRichHandsome = 0b00000000
    }
    
    var tall:Bool? {
        set{
            if newValue == true {
                _tallRichHandsome |= YZTallMask
            } else {
                _tallRichHandsome &= ~YZTallMask
            }
        }
        get {
            let result  = _tallRichHandsome & YZTallMask
            return result == 0 ? false : true
        }
    }
    
    var rich:Bool? {
        set{
            if newValue == true {
//按位取 | 运算 能够把想要的位置设为1 不影响其他位
                _tallRichHandsome |= YZRichMask
            } else {
//按位取反 然后&运算 能够把想要的位置设为0 不影响其他位
                _tallRichHandsome &= ~YZRichMask
            }
        }
        get {
//想要取出某一位的值 需要用掩码进行与运算 只要不是0 就是1
            let result  = _tallRichHandsome & YZRichMask
            return result == 0 ? false : true
        }
    }
    
    var handsome:Bool? {
        set{
            if newValue == true {
                _tallRichHandsome |= YZHandsomeMask
            } else {
                _tallRichHandsome &= ~YZHandsomeMask
            }
        }
        get {
            let result  = _tallRichHandsome & YZHandsomeMask
            return result == 0 ? false : true
        }
    }
    
    
}

class BitwiseSaveVC: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        
        let person = YZPerson()
        
        //        person._tallRichHandsome =  0b00000101
        //
        //        print("person.tall == \(person.tall!),person.rich == \(person.rich!),person.handsome == \(person.handsome!)")
        
        person.tall = true
        person.handsome = true
        person.rich = true
        
        print("person._tallRichHandsome = \(person._tallRichHandsome)")
        let bittallRichHandsome = String(person._tallRichHandsome,radix: 2)
        print("person._tallRichHandsome = \(bittallRichHandsome)")
        
    }

输出

person._tallRichHandsome = 7
person._tallRichHandsome = 111

OC 优化版本

  • 不知道怎么用swift 写 位域 结构体 所以这里用OC

@interface YZPerson2 ()
{
    struct {
        char tall : 1 ;
        char rich : 1 ;
        char handsome : 1;
        
    }_tallRichHandsome;
}


@end
@implementation YZPerson2

-(void)setTall:(BOOL)tall{
    _tallRichHandsome.tall = tall ;
}
-(BOOL)isTall{
    //取两次反的原因是 tall 是一个2进制位 再转换成 bool 时候需要变成8位,容易从1变成-1  两次取反的就是为了去取bool值
    return  !!_tallRichHandsome.tall ;
}
-(void)setRich:(BOOL)rich{
    _tallRichHandsome.rich = rich ;
}
-(BOOL)isRich{
    return  !!_tallRichHandsome.rich ;
}
-(void)setHandsome:(BOOL)handsome{
    _tallRichHandsome.handsome = handsome ;
}
-(BOOL)isHandsome{
    return  !!_tallRichHandsome.handsome ;
}

union 共用体

#define YZTallMask  (1<<0)
#define YZRichMask  (1<<1)
#define YZHandsomeMask  (1<<2)
@interface YZPerson2 ()
{
    union {
        char bits;
        //**这个结构体是为了增加可读性 不写也可以**
//        struct {
//            char tall : 1 ;
//            char rich : 1 ;
//            char handsome : 1;
//
//        };
    }_tallRichHandsome;
 
}


@end
@implementation YZPerson2

-(void)setTall:(BOOL)tall{
    if(tall){
        _tallRichHandsome.bits |=  YZTallMask;
    } else {
        _tallRichHandsome.bits &=  ~YZTallMask;
    }
}
-(BOOL)tall{
   
    return  !!(_tallRichHandsome.bits &  YZTallMask );
}
-(void)setRich:(BOOL)rich{
    if(rich){
           _tallRichHandsome.bits |=  YZRichMask;
       } else {
           _tallRichHandsome.bits &=  ~YZRichMask;
       }
}
-(BOOL)rich{
    return   !!(_tallRichHandsome.bits &  YZRichMask );
}
-(void)setHandsome:(BOOL)handsome{
    if(handsome){
        _tallRichHandsome.bits |=  YZHandsomeMask;
    } else {
        _tallRichHandsome.bits &=  ~YZHandsomeMask;
    }
}
-(BOOL)handsome{
    return !!(_tallRichHandsome.bits &  YZHandsomeMask );
}

@end

class对象、meta-class对象 的地址值最后三位一定是0

枚举里面的位运算

//这种最好用OC 写 Swift贼麻烦
typedef enum {
    YZOptionNone = 0,
    YZOptionOne = 1<<0, //0b0001
    YZOptionTwo = 1<<1,//0b0010
    YZOptionThree = 1<<2,
    YZOptionFour = 1<<3,
    
}YZOption;

-(void)setOptions:(YZOption)op{
    if (op & YZOptionOne) {
        NSLog(@" 包含了 YZOptionOne ");
    }
    if (op & YZOptionTwo) {
        NSLog(@" 包含了 YZOptionTwo ");
    }
    
    if (op & YZOptionThree) {
        NSLog(@" 包含了 YZOptionThree ");
    }
    
    if (op & YZOptionFour) {
        NSLog(@" 包含了 YZOptionFour ");
    }
    
}
 [self setOptions:YZOptionOne | YZOptionFour | YZOptionThree];

相关文章

网友评论

      本文标题:Runtime知识点整理1

      本文链接:https://www.haomeiwen.com/subject/beennhtx.html