【OC底层-类和对象深基】

news2024/11/15 9:37:09

文章目录

  • 前言
  • 1 类和对象
    • 1.1 类
      • `1.1.1 cache_t 和 class_data_bits_t`
    • 1.2 对象
  • 2 isa指针(结构体)
    • 复习-OC中的对象
      • 实例对象(Instance)
      • 类对象(Class)
      • 元类对象
      • isa的指向
      • 方法调用顺序(不涉及消息转发)
    • 2.1 union简单了解
    • 2.2 isa的初始化
      • 2.2.1 objc_object::initIsa
    • 2.3 Class
    • 2.4 objc_Class的源码部分
        • 2.4.1 class_rw_t, class_ro_t
          • 区别和联系
        • 总结
        • 2.4.2 cache_t
        • 2.4.5 property_t
    • 2.5 category不能添加成员变量
    • 2.6 类方法为什么在元类里面?
    • OC类的信息存放在哪里
  • 最后的点

前言

分析了对象,类及其父类元类的关系之后,类和对象的底层实现是需要我们更多的学习的,在之后的消息转发,包括源码的部分结构体,包括RunLoop等等或多或少都会涉及OC类和对象的底层。

我个人认为深究类和对象的深入底层的代码较为繁琐看不懂也记不住,对于类和对象 isa_t指针是重中之重,跟着这个指针向下一步一步探索,能看懂多少就看造化了。

1 类和对象

1.1 类

在OC中,类和对象的本质是基于C/C++的结构体,编译时期会以结构体的形式被编译到二进制里面。

  • 因为在源码直接看不到类的剧具体定义,直接跳转NSObject的实现。
    请添加图片描述
  • 通过查看NSObject的类定义,可以看到内部有一个Class isa的成员变量. 从Apple开放的objc源码来看,可以发现,Class类型是一个结构体指针
  • 继续看objc_class的实现 发现objc_class是继承于objc_object的结构体.而objc_object内部.只存放了isa变量.
    请添加图片描述
  • objc_class的 Class ISA
struct objc_class : objc_object {
    // Class ISA;
    Class superclass;          // 指向父类的Class结构体
    cache_t cache;             // formerly cache pointer and vtable 缓存结构体,用于加速方法查找。
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags 个字段包含了一些标志位和其他信息,用于描述该类对象的一些特性。

可以看到objc_class继承于objc_object,也就是类的本质也是对象(元类的学习讲到过)

那么类的学习也可以归为对象的学习的一部分

也就是都要深基isa结构体,对于类的isa :每个类的 isa 指针都指向它的父类的 Class 结构体,直到指向 NSObject 类为止。这就形成了一个类的继承结构,同时也支持多态和动态绑定等面向对象编程的特性

1.1.1 cache_t 和 class_data_bits_t

cache_t

  • 在 Objective-C 中,每个类都有一个方法缓存,用于加速方法查找。当程序需要调用一个对象的方法时,它首先在缓存中查找该方法,如果找到了就直接调用,否则就在类的方法列表中进行查找。这个过程会被重复执行,以便于提高方法查找的效率。
  • cache_t 是一个缓存结构体,它包含了一些关于方法缓存的信息,例如缓存的大小、已经缓存的方法数量、缓存的方法列表等等。在 Objective-C 中,缓存是在运行时创建并维护的,通过使用缓存可以显著提高方法调用的速度。
  • 因此,定义一个 cache_t 类型的变量 cache 可以用于对方法缓存进行操作,例如查询缓存中是否存在指定的方法、向缓存中添加方法等等。

class_data_bits_t

  • 这个字段包含了一些标志位和其他信息,用于描述该类对象的一些特性。

1.2 对象

对象的结构体在上一章说过了,在objc834可编译源码看看如何实现

请添加图片描述

这里是C++的面相对象思想 ,私有和公开。

抛开公开的方法部分,发现对象的结构体里面有一个名为isaisa_t类型的成员变量

struct objc_object {
private:
    isa_t isa;

public:
....省略方法部分

对象的本质除了其本身含有的方法列表,它有一个isa指针又来存储其所属类的信息。

在 Objective-C 中,每个对象都有一个 isa 指针,指向它的类对象。isa 指针实际上是一个指向一个 Class 结构体的指针,这个结构体包含了与类相关的一些信息,包括:

  • 类的名字;
  • 父类的指针;
  • 类的成员变量列表;
  • 类的属性列表;
  • 类的方法列表;
  • 类的协议列表。

2 isa指针(结构体)

  • 需要了解元类 理解OC的类,父类,元类的关系

在64位系统之前,isa是一个普通的指针,存放着类对象和元类对象的地址值,在64位系统里面,isa变成了一个共用体结构(union),同时使用位域来存储更多的信息。(这里涉及到共用内存以及位域的概念)网上查找补充的

isa结构体

union isa_t 
{
    Class cls;
    uintptr_t bits;
    struct {
         uintptr_t nonpointer        : 1;//->表示使用优化的isa指针
         uintptr_t has_assoc         : 1;//->是否包含关联对象
         uintptr_t has_cxx_dtor      : 1;//->是否设置了析构函数,如果没有,释放对象更快
         uintptr_t shiftcls          : 33; // MACH_VM_MAX_ADDRESS 0x1000000000 ->类的指针
         uintptr_t magic             : 6;//->固定值,用于判断是否完成初始化
         uintptr_t weakly_referenced : 1;//->对象是否被弱引用
         uintptr_t deallocating      : 1;//->对象是否正在销毁
         uintptr_t has_sidetable_rc  : 1;//1->在extra_rc存储引用计数将要溢出的时候,借助Sidetable(散列表)存储引用计数,has_sidetable_rc设置成1
         uintptr_t extra_rc          : 19;  //->存储引用计数
    };
};

复习-OC中的对象

要在这里讲一下isa指针的指向问题和方法的调用顺序,再次复习一下OC的对象。

实例对象(Instance)

实例对象,顾名思义就是类的实例对象.当一个类的实例对象在堆中alloc时.内存中存放的是实例对象的isa以及成员变量.至于方法.是通过isa找到对应类对象.再寻找对应的方法进行调用

类对象(Class)

OC的类对象,其实我们上面已经讲过了.类对象存放了isa.成员变量列表.属性列表.方法列表.协议列表.但是值得注意的一点是,类对象中存放的方法为实例方法

元类对象

元类对象.是类对象的元类对象.元类对象的结构与类对象基本一致.但是存放的是类的类方法

类对象存放的是实例方法.元类对象存放的是类方法

isa的指向

对象的isa ===> 类
类的isa ===> 元类(metaClass)

元类(metaClass)的isa ===>父类 ===> RootMetaClass(根元类)

RootMetaClass(根元类)的isa ===> RootMetaClass(根元类)

类对象的superClass ===> 父类 ===> rootClass(根类) ===> nil

元类的superClass ==> 父元类 ===> metaRootClass (根元类) ===> rootClass(根类) ===> nil
在这里插入图片描述

方法调用顺序(不涉及消息转发)

调用实例对象方法时

  • 通过isa找到对象的类,然后查找类中的方法列表,
  • 如果找不到,通过superClass找到父类
  • 最终到根类.如果都找不到.程序崩溃(unrecognize selector)

调用类方法时

  • 通过isa找到元类,查找类方法列表
  • 层层向上.到根元类.
  • 最终到根类.根元类isa指向根类.都找不到.崩溃

2.1 union简单了解

为了理解isa_t的实现过程,简单了解一下union

在 Objective-C 中,union 是一种数据类型,它可以将多个不同的数据类型共享同一个内存空间。换句话说,它允许程序员在同一个内存地址上存储不同类型的数据。

一个 union 可以包含多个成员变量,每个成员变量可以是不同的数据类型,但是 union 只会为其中一个成员变量分配内存空间,这个空间的大小是所有成员变量中最大的一个。

2.2 isa的初始化

通过isa_t的结构可以得出根据union的定义,cls和bits这两个成员变量是互斥的,这也决定了isa指针初始化的时候有两种初始化方式

  • 通过cls初始化,bits无默认值
  • 通过bits初始化,cls有默认值、

请添加图片描述

2.2.1 objc_object::initIsa

isa的初始化会调用两层函数

objc_object::initIsa->objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)

表层:objc_object::initIsa
请添加图片描述

跳转到 objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)

请添加图片描述

inline void 
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{
    ASSERT(!cls->instancesRequireRawIsa());
    ASSERT(hasCxxDtor == cls->hasCxxDtor());

    initIsa(cls, true, hasCxxDtor);
}

#if !SUPPORT_INDEXED_ISA && !ISA_HAS_CXX_DTOR_BIT
#define UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT __attribute__((unused))
#else
#define UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT
#endif

inline void 
objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)
{ 
    ASSERT(!isTaggedPointer()); 
    
    isa_t newisa(0);

    if (!nonpointer) {
        newisa.setClass(cls, this);
    } else {
        ASSERT(!DisableNonpointerIsa);
        ASSERT(!cls->instancesRequireRawIsa());


#if SUPPORT_INDEXED_ISA
        ASSERT(cls->classArrayIndex() > 0);
        newisa.bits = ISA_INDEX_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
        newisa.has_cxx_dtor = hasCxxDtor;
        newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
        newisa.bits = ISA_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
#   if ISA_HAS_CXX_DTOR_BIT
        newisa.has_cxx_dtor = hasCxxDtor;
#   endif
        newisa.setClass(cls, this);
#endif
        newisa.extra_rc = 1;
    }

    // This write must be performed in a single store in some cases
    // (for example when realizing a class because other threads
    // may simultaneously try to use the class).
    // fixme use atomics here to guarantee single-store and to
    // guarantee memory order w.r.t. the class index table
    // ...but not too atomic because we don't want to hurt instantiation
    isa = newisa;
}

  • 首先是assert函数:在 Objective-C 中,assert 函数用于进行断言检查,它是一个宏定义,通常用于验证程序中的条件是否满足。如果断言的条件为假,即不满足预期,assert 函数会触发一个断言失败的错误,并终止程序的执行。
void assert(int expression);

例如

int x = 5;
assert(x > 0);  // 检查 x 是否大于 0,如果为假,则触发断言失败

如果 x 的值不大于 0,assert 函数会触发断言失败,程序会中止执行,并在标准错误流中输出相应的错误信息。

  • 接着进行isa初始化,注释写到
    isa.magicisa_magic_VALUE的一部分
    isa.nonpointerisa_MAGIC_VALUE的一部分
 newisa.bits = ISA_INDEX_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
        

也就是news.bits初始化时候只设置了nonpointer,magic两个部分。

  • 接着has_cxx_dtor的赋值(->是否设置了析构函数,如果没有,释放对象更快)
newisa.has_cxx_dtor = hasCxxDtor;
newisa.indexcls = (uintptr_t)cls->classArrayIndex();

2.3 Class

  • class ObjectClass = [[nsobject class]class]; 返回的还是class对象,并不是meta-class对象.
    使用Class metaClass = objc_getMetaClass("ClassName"); 获取元类对象
  • 类对象在内存中有且仅有一个对象 主要包括 isa指针 super Class指针 类的属性信息 类的对象方法信息 类的协议信息 类的成员变量信息
  • 元类对象和class内存结构是一样的 但是用途不一样 主要有类方法的类信息 其他为空的
//     instacne对象
    NSObject *obj1 = [[NSObject alloc] init];
    NSObject *obj2 = [[NSObject alloc] init];

    //类对象
    Class objClass1 = [obj1 class];
    Class objClass2 = [obj2 class];
    Class objClass3 = [NSObject class];
    Class objClass4 = object_getClass(obj1);
    Class objClass5 = object_getClass(obj2);
    
    // 元类对象
    Class objcMetaClass = object_getClass([NSObject class]);
    Class objcMetaClass2 = [[NSObject class] class];
    
    // 获取元类对象
    Class metaClass = objc_getMetaClass("NSObject");
    NSLog(@"instance - %p %p", obj1, obj2);
    NSLog(@"class - %p %p %p %p %p %d", objClass1, objClass2, objClass3, objClass4, objClass5, class_isMetaClass(objClass3));
    NSLog(@"mateClass - %p %p %d",objcMetaClass, objcMetaClass2, class_isMetaClass(objcMetaClass));
    NSLog(@"%@", metaClass);
}

// class方法得到的都还是类函数

2.4 objc_Class的源码部分

  • 关于objc_Class的isa指针的变量已经说过了
// Class ISA;
    Class superclass;
    cache_t cache;              // 方法缓存 formerly cache pointer and vtable
    class_data_bits_t bits;    // 用于获取具体的类信息 class_rw_t * plus custom rr/alloc flagsflags
    ...

这里需要说的是 bits

bits里面存储了类的方法列表等等信息,是class_data_bits_t类型的结构体。

public:

    class_rw_t* data() const {
        return (class_rw_t *)(bits & FAST_DATA_MASK);
    }
    void setData(class_rw_t *newData)
    {
        ASSERT(!data()  ||  (newData->flags & (RW_REALIZING | RW_FUTURE)));
        // Set during realization or construction only. No locking needed.
        // Use a store-release fence because there may be concurrent
        // readers of data and data's contents.
        uintptr_t newBits = (bits & ~FAST_DATA_MASK) | (uintptr_t)newData;
        atomic_thread_fence(memory_order_release);
        bits = newBits;
    }

    // Get the class's ro data, even in the presence of concurrent realization.
    // fixme this isn't really safe without a compiler barrier at least
    // and probably a memory barrier when realizeClass changes the data field
    const class_ro_t *safe_ro() const {
        class_rw_t *maybe_rw = data();
        if (maybe_rw->flags & RW_REALIZED) {
            // maybe_rw is rw
            return maybe_rw->ro();
        } else {
            // maybe_rw is actually ro
            return (class_ro_t *)maybe_rw;
        }
    }

需要知道 bits里面的class_rw_t, class_ro_t
(readwrite, readonly)

2.4.1 class_rw_t, class_ro_t

class_rw_tclass_ro_t 是用来描述类信息的两个结构体

  • class_rw_t 结构体表示类的可写信息,包含了类的实例变量、属性、方法等信息。
    在这里插入图片描述
  • class_ro_t 结构体表示类的只读信息,包含了类的名称、父类、实例变量、属性、方法等信息。
    在这里插入图片描述
区别和联系
  1. 可写信息和只读信息:
  • class_rw_t 结构体表示类的可写信息,包括类的方法列表、属性列表、协议列表等。这些信息可以在运行时进行修改。
  • class_ro_t 结构体表示类的只读信息,包括类的名称、父类、实例变量、基本方法列表、基本协议列表等。这些信息在类加载时被初始化,之后不可更改。
  1. 指针引用:
  • class_rw_t 结构体中的 ro 指针指向对应类的 class_ro_t 结构体,用于访问类的只读信息。
  • class_ro_t 结构体中的 baseMethodsbaseProtocolsivarsweakIvarLayoutbaseProperties 等指针分别指向对应的方法列表、协议列表、实例变量列表、弱引用实例变量布局、属性列表等。
  1. 功能和用途:
  • class_rw_t 结构体用于描述类的可写信息,可以用来修改类的方法、属性、协议等,以及添加新的方- 法。
  • class_ro_t 结构体用于描述类的只读信息,包括类的静态属性、方法列表、协议列表等,用于获取类的基本信息。
    通过runtime动态修改类的方法时,其实是修改在class_rw_t区域中存储的方法列表
    请添加图片描述
    ro编译阶段生成,rw运行的时候生成。从存储的内容角度来讲,ro中有方法、属性、协议和成员变量,而rw中并没有成员变量。rw中的方法属性协议的取值方法中,也是通过取ro或者rwe中的值来获得。ro中的方法、属性、协议都是base,也就是只有本类中的方法属性和协议

总结

编写代码运行后,开始类的方法,成员变量 属性 协议等信息都存放在 const class_ro_t
运行过程中,会将信息整合,动态创建 class_rw_t
然后会将 class_ro_t中的内容(类的原始信息:方法 属性 成员变量 协议信息) 和 分类的方法 属性 协议 成员变量的信息 存储到 class_rw_t中.并通过数组进行排序,分类方法放在数组的前端,原类信息放在数组的后端.
初始运行时 objc-class中的 bits是指向 class_ro_t的,bits中的data取值是从class_ro_t中获得,而后创建 class_rw_t,class_rw_t中的 class_ro_t从初始的 class_ro_t中取值(所以这两个不是一个对象),class_rw_t初始化完成后,修改 objc_class中的bits指针指向class_rw_t

2.4.2 cache_t

struct cache_t {
	    struct bucket_t *buckets() const;
	    mask_t mask() const;
	    mask_t occupied() const;
}

这里引入了bucket_t(散列表),是cache的内部哈希结构
bucket_t中存储的是SEL和IMP的键值对
请添加图片描述

2.4.5 property_t

只储存了其name和属性关键字

struct property_t {
    const char *name; // 类型的指针,表示属性的名称。
    const char *attributes; // 类型的指针,表示属性的特性,包括读写权限、属性类型、内存管理等信息。
};

  • 在真正访问的时候,访问的实例变量(该结构体只是属性信息的一个描述,不包含实际的属性值。在实际使用中,需要将属性信息与具体的对象实例关联起来,才能真正地使用属性。)

2.5 category不能添加成员变量

在之前关联对象的源码也学习过,因为因为category是运行时添加的,他只能操作class_rw_t结构,但是class_rw_t结构没有添加成员变量的入口。成员变量是存储在class_ro_t中的,是无法被修改的,所以category就不能添加成员变量。

2.6 类方法为什么在元类里面?

  • 单一职责设计原理。
    实例对象存储成员变量的值,类对象存放,实例方法、协议、成员变量、属性,元类对象存放类方法,各司其职,互不影响。
  • 复用msgSend消息发送机制。
    类方法、实例方法是在上层的定义,在底层并不区分类方法实例方法,但在runtime这一层,需要承接上层类方法和实例方法,对接到底层方法调用。使用了msgSend,如果msgSend的时候需要再区分类对象,实例对象,会在内部增加判读逻辑,从而降低了效率,有了元类的存在,问题迎刃而解。

OC类的信息存放在哪里

  • 对象方法、属性、成员变量、协议信息,存放在class对象中
  • 类方法存放在meta-class对象中(元类对象和class内存结构是一样的 但是用途不一样 主要有类方法的类信息 其他为空的)
  • 成员变量的具体值存放在instance对象中

最后的点

  • 对于类和对象 这篇学习从 类 父类 元类开始,到分析 对象的结构 类的结构学习到了isa指针 知道类的本质也是对象,接着了解到了union,知道了isa的初始化两种方法,接着学习objcet_class的源码 学习到了ClassISA的cache和bits,进一步了解了编译和运行时期的过程总结,通过类和元类的学习,知道了类调用方法和对象调用方法的顺序和区别,最后总结了一点小小的问题,至少对类和对象的内部结构有了更深的理解,在之后的源码学习过程和消息转发等机制中打了基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/511519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScrip 实战案例之【实现动画导航栏效果】

​Hello~ 咱们今天一起来学习一个动画导航的小项目 Part 1 HTML结构 <body><nav class"active" id"nav"><ul><li><a href"#">Home</a></li><li><a href"#">Works</a>&…

Cy5.5-PEG-NH2/SH/COOH/MAL,NH2-PEG-Cy5.5;CY5.5-聚乙二醇-氨基文章介绍

Cy5.5-PEG-NH2 cy5.5-聚乙二醇-氨基 中文名称&#xff1a;CY5.5-聚乙二醇-氨基 英文名称&#xff1a;Cy5.5-PEG-NH2 溶剂&#xff1a;溶于水、氯仿&#xff0c;DMSO等常规性有机溶剂 性状&#xff1a;固体或粉末&#xff0c;取决于分子量 分子量&#xff1a;1k、2k、3.4k、…

计算机视觉(4)—— 未有深度学习之前

目录 四、未有深度学习之前 4.1 图像分割 4.1.1 基于阈值分割 4.1.2 基于边缘分割 4.1.3 基于区域分割 &#xff08;1&#xff09;区域生长法 &#xff08;2&#xff09;分水岭算法 4.1.4 基于图论分割 &#xff08;1&#xff09;Graph Cuts 分割 ​&#xff08;2&…

关于说服(三)- 表达

关于口才 一般人眼中的口才好&#xff1a; 有见解&#xff0c;有想法内容条理分明&#xff0c;逻辑清晰严谨真诚自信&#xff0c;拉近距离 这些都关注于逻辑与内容&#xff0c;真正的表达是要教你如何输出有价值的信息 表达需要做什么&#xff1a; 如何筛选素材&#xff0c…

【P16】JMeter JSON提取器(JSON Extractor)

文章目录 一、准备工作二、测试计划设计 一、准备工作 慕慕生鲜&#xff1a; http://111.231.103.117/#/login 进入网页后&#xff0c;登录&#xff0c;页面提供了账户和密码 搜索框输入“虾” 右键检查或按F12&#xff0c;打开调试工具&#xff0c;点击搜索 二、测试计划设…

Cy5.5-PEG-FA结构式 荧光Cy5.5标记聚乙二醇叶酸;PEG分子量2000,叶酸(-FA)基团可应用于靶向传递

Cy5.5-PEG-FA&#xff0c;Cy5.5-聚乙二醇-叶酸 中文名称&#xff1a;Cy5.5-聚乙二醇-叶酸 英文名称&#xff1a;Cy5.5-PEG-FA 溶剂&#xff1a;溶于水、氯仿&#xff0c;DMSO等常规性有机溶剂 性状&#xff1a;固体或粉末&#xff0c;取决于分子量 分子量&#xff1a;1k、…

OSS 文件文件夹 直接打包下载

前言 OSS 存放了很多项目&#xff08;项目是 TMagic 低代码平台编辑生成&#xff0c;自动上传 OSS&#xff09;&#xff0c;现在需要在管理后台将项目打包ZIP下载&#xff0c;并不在本地生成文件。 OSS 要下载项目文件&#xff1a; 一、思路实现 创建 OSSClient 实例获取 Bu…

198页11万字智慧水务平台建设方案(word)

目 录 一、项目概述 1、建设背景 2、存在问题 2、运营分析 二、支持技术 1、3S技术 2、物联网技术 3、富客户端技术 4、移动互联网技术 三、建设目标 三、需求分析 1、系统用户 2、调度管理对象 3、业务需求分析 3.1 主要业务描述 3.2 业务需求…

Mal-PEG2000-Cy5.5;Cy5.5-PEG-Maleimide 花箐染料Cy5.5-聚乙二醇-马来酰亚胺

CY5.5-PEG-Mal&#xff0c;CY5.5-聚乙二醇-马来酰亚胺 中文名称&#xff1a;CY5.5-聚乙二醇-马来酰亚胺 英文名称&#xff1a;CY5.5-PEG-Mal&#xff0c; Cy5.5-PEG-Maleimide 溶剂&#xff1a;溶于水、氯仿&#xff0c;DMSO等常规性有机溶剂 性状&#xff1a;固体或粉末&a…

车载以太网 - SomeIP - TC8用例常见缩写

对于初接触SomeIP的朋友来说,看测试用例最大的烦恼我想不仅仅是来自纯英文的描述,更多的一定无休止的缩写,那这些缩写到底代表什么意思呢,我也是深受其害的人,因此就把对应的缩写、中文、英文整理出来了,希望能对大家有所帮助。 常见缩写及中英文注释 SomeIP常见缩写英文…

第一章 电路模型和电路定律(习题解析)

第一章 电路模型和电路定律&#xff08;习题解析&#xff09; 简介&#xff1a; 书后面的习题详解&#xff0c;主要包含的内容关联方向与非关联方向、功率平衡 电路基础&#xff08;第一章电路模型和电路定律&#xff09;第一章电路模型和电路定律&#xff08;补充&#xff09;…

Bentley ContextCapture Center操作入门(1)

什么是ContextCapture Center 使用照片或激光雷达点云为城市等最大规模的项目生成详细的 3D 实景网格。 ContextCapture Center具有强大的计算能力&#xff0c;可以轻松处理非常大的项目。它利用网格计算&#xff0c;通过在多台计算机上运行多个引擎并将它们关联到单个作业队列…

261页10万字政务服务一网通办平台建设方案(word)

目 录 第1章 项目建设概述 1.1 建设背景 1.2 建设意义 1.3 现状分析 1.4 建设目标 1.4.1 政务服务标准化 1.4.2 政务服务精准化 1.4.3 政务服务便捷化 1.4.4 政务服务平台化 1.4.5 政务服务协同化 1.5 建设原则 1.6 建设内容 1.7 编制依据 &#x…

前端本地存储方案-localForage

1 前言 前端有多种本地存储方案可供选择&#xff0c;以下是其中一些常见的方案&#xff1a; Cookie&#xff1a;Cookie是一种小型的文本文件&#xff0c;可以在浏览器中存储少量数据。Cookie通常用于存储会话信息或用户偏好设置等数据&#xff08;只能存储少量数据&#xff0…

动态规划-数字三角形模型

title: 数字三角形模型 date: 2023-05-10 14:26:11 categories: Algorithm动态规划 tags:动态规划数字三角形 数字三角形 Number Triangles 题目描述 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每一步可…

Cy5.5-聚乙二醇-羟基;PEG2000;Cy5.5-PEG-OH结构式以及相关信息介绍

中文名称Cy5.5-聚乙二醇-羟基 英文名称Cy5.5-PEG-OH 性状&#xff1a;蓝色或深蓝色固体或粘性液体&#xff0c;取决于分子量 溶剂&#xff1a;溶于水、氯仿、DMSO等常规性有机溶剂 激发/发射波长&#xff1a;655nm/678nm 分子量PEG:1k、2k、3.4k、5k其他分子量可以制定 分…

vue3 - 实现文字横向滚动 / 垂直翻滚功能组件,类似喇叭广告、公告、跑马灯的文字滚动效果(详细组件源码与注释,一键复制开箱即用!)

效果图 在 vue3.js 项目中,完成了文字横向 / 纵向自动重复滚动效果组件,支持设置滚动区域宽高、背景色、展示条数、滚动间隔、横向纵向-方向切换等等,丝滑流畅! 无任何第三方插件依赖,详细的示例及注释,轻松一键复制组件源码开箱即用! 第一步 创建文字滚动组件TextSc…

22年山东省B-2网页渗透测试

首先这道题目就是ip/1找flag的题目,所以我们直接来看环境: 这个题目直接使用抓包 修改头部即可拿到flag 我们接着看一道题目: 这道题目

输入url后,到页面展示出来

目录 1、用户在浏览器中输入url地址 2、缓存解析 3、浏览器进行DNS解析域名得到服务器ip地址 4、TCP三次握手建立客户端和服务器的连接 5、客户端发送HTTP请求获取服务器端的静态资源 6、服务器发送HTTP响应报文给客户端&#xff0c;客户端获取到页面静态资源 7、TCP四次…

探索文本生成世界:原理、技术与应用

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…