2. objC 动态绑定(dynamic binding)

【C++中的动态绑定】从小白到高手,一文搞懂! 摘要:本文通俗易懂地讲解了C++中的动态绑定机制,重点介绍了虚函数在多态实现中的关键作用。通过动物类继承的代码示例,演示了如何使用基类指针调用派生类函数,对比了静态绑定和动态绑定的区别。文章还指出了动态绑定的实现原理(虚函数表vtable)和常见注意事项,最后强调了动态绑定对C++面向对象编程的重要性。适合C++初学者理解多态概念,配有详细注释的代码实例和通俗比喻。 阅读详情

1 动态绑定理解

       动态绑定,在编译期间,不能决定当前调用函数的地址;在程序运行时,通过当前对象的类型来判断当前调用函数的地址所在。这一点和C和C++不同,在C中,所有函数的调用都是在编译过程中所决定的。在C++中,只有virtual函数的调用是通过v-table在运行时进行查找的,其他都是静态调用。

      动态调用速度慢,静态调用速度快。

2 动态绑定原理

2.1 SEL

     SEL 是objc_selector结构的指针,objc_selector的结构如下

     objc_selector 的GNU Objective-C的实现

typedefconststructobjc_selector
{
  void *sel_id;
  constchar *sel_types;
} *SEL

     objc_selector 的NeXT Objective-C的实现

     没有查到相关的文档,在相关文章中,其实现直接就是一个字符串。从此函数也可以知道

      NSLog(@"%s",@selector(say: usingLag:);将打印出say:usingLag:。说明@selector只是简单的翻译,不判断say:usingLag:函数是否被某个类定义过。

2.2 IMP

     IMP是一个obj-c中,内部定义的函数指针:

/*
** Definition of method type. When retrieving the implementation of a
** method, this is type of the pointer returned
*/
typedefid (*IMP)(id, SEL


     向Child的对象pChild发送say:(int) LagType的消息,[pChild say:0]。编译器会将上边的代码翻译为id objc_msgSend(pChild, @selector(say:), LagType);其中,此函数申明为id objc_msgSend(id theReceiver, SEL theSelector, ...),此函数将在theReceiver中isa所指向的类对象的objc_method_list方法列表中去查找SEL所对应的IMP函数地址,进而进行执行。

    /**  Method Template */
    typedef struct objc_method *Method;
    struct objc_method {
        SELmethod_name;
        char *method_types;
        IMPmethod_imp;
    };
    struct objc_method_list {
        struct objc_method_list *obsolete;
        int method_count;
#ifdef __alpha__        
        int space;
#endif    
        struct objc_methodmethod_list[1];  /* variable length structure */
    };

2.3 性能

       显然,这种函数的调用的方法,显然要比静态绑定要慢的多。于是,在程序中,我们常常可以把函数的地址先记录下来,然后直接进行调用。如下边的代码,但是,通过我们实际测速,这两种方式,基本上相差很少,是由于在Class中还有一个方法地址的Cache,会大大加快函数调用方法。所以,在实际的调用过程中,objC的函数调用没有象想象中的那么慢。

例如:

patient.h文件

@interface Person : NSObject
{
@privateNSMutableString* name;
@privateNSMutableString* uid;
@privateNSDate* birthday;
@privateNSString* sex;
}
@property(nonatomic, retain) NSMutableString* name;
@property(nonatomic, retain) NSMutableString* uid;
@property(nonatomic, retain) NSDate* birthday;
@property(nonatomic, retain) NSString* sex;
/**
 */
-(id) init:(NSMutableString*) persionId andBirthDay:(NSDate*) birth;
-(void) printOut;
@end

/**the below is about the Patient
 */
@interface Patient: Person
{
@privateNSMutableString* medical_insure_card_id;
}
@property(nonatomic, retain) NSMutableString* medical_insure_card_id;

-(id) init:(NSMutableString*) personId andBirthDay:(NSDate *)birth andMedicalInsureCardId:(NSMutableString*) cardId;
-(void) printOut;
@end

/***/
@interface PaitentCreator:NSObject
+(Patient*) CreatePatient;
@end
patient.m文件

@implementation Person

@synthesize name;
@synthesize uid;
@synthesize birthday;
@synthesize sex;
-(id) init:(NSMutableString*) persionId andBirthDay:(NSDate*) birth
{
    id temp = [superinit];
    if (!temp || self != temp)
    {
        returnnil;
    }
    self.uid = persionId;
    self.birthday = birth;
    returnself;
}
-(void) printOut
{
    //NSLog(@"the person name is %@ uid = %@ birthday = %@",self.name,self.uid,[self.birthday description] );
    NSLog(@"the person name is %@ ",self.name);
}
-(void)dealloc
{
    if (uid != nil) {
        [uidrelease];
        uid = nil;
        NSLog(@"uid release");
    }
    if (birthday != nil) {
        [birthdayrelease];
        birthday = nil;
        NSLog(@"birthday release");
    }
    if (sex != nil) {
        [sexrelease];
        sex = nil;
        NSLog(@"sex release");
    }
    if(name != nil)
    {
        [namerelease];
        name = nil;
        NSLog(@"name release");
    }
    [superdealloc];
}
@end

@implementation Patient
@synthesize medical_insure_card_id;
-(id) init:(NSMutableString*) personId andBirthDay:(NSDate *)birth andMedicalInsureCardId:(NSMutableString*) cardId
{
    id temp = [superinit:personId andBirthDay:birth];
    if (!temp || self != temp) {
        returnnil;
    }
    self.medical_insure_card_id = cardId;
    returnself;
}
-(void) printOut
{
    [superprintOut];
    //NSLog(@"the patient medical card id = %@",self.medical_insure_card_id);
}
-(void) dealloc
{
    if(medical_insure_card_id != nil)
    {
        [medical_insure_card_idrelease];
        medical_insure_card_id = nil;
    }
    [superdealloc];
}
@end


@implementation PaitentCreator
+(Patient*) CreatePatient
{
    Patient* pTempPatient = [[Patientalloc] init];
    [pTempPatient autorelease];
    return pTempPatient;
}
@end 
main.m
typedef void (*PrintInformation)(id, SEL);

        Patient* patient = [[Patientalloc] init:[[NSMutableStringalloc] initWithString:@"12345678"] andBirthDay: [NSDatedate] andMedicalInsureCardId:[[NSMutableStringalloc] initWithString:@"bj_jst_2012.1.21_beijing_china"]];
        patient.name = [[NSMutableStringalloc] initWithString:@"Zhao^QiaoZhuan^^^"];
        
    

        PrintInformation printFun = nil;
        printFun = (PrintInformation)[patient methodForSelector:@selector(printOut)];
        
        for (int i = 0; i < 10000; ++i) {
            printFun(patient,@selector(printOut));
        }//12286 - 7643 = 4643ms
        NSLog(@"------------------------------------------------------------------");
        NSLog(@"------------------------------------------------------------------");
        NSLog(@"------------------------------------------------------------------");
        for (int i = 0; i < 10000; ++i) {
            [patient printOut];
        }//16988 - 12287 = 4701ms

        回想,在第一节中dynamic typing的讲解,知道performSelector等函数是和动态绑定中,查找函数有关系的。






FPGA波束形成:从算法到硬件的艺术之旅 本文深入探讨了FPGA在波束形成技术中的应用,从算法原理到Verilog硬件实现的全过程。文章详细分析了FPGA并行处理、低延迟和可重构特性如何优化波束形成系统性能,并提供了Verilog关键模块代码示例和资源优化策略,为工程师实现高效FPGA波束形成解决方案提供实用指导。 阅读详情

相关推荐

常用的数据结构以及常用的算法

常用的数据结构以及常用的算法 常用数据结构 数据结构是计算机存储、组织数据的方式。 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。 数据结构往往同高效的检索算法和索引技术有关。 一、线性表 线性结构: 最常用、最简单的一种数据结构。 线性表: 典型的线性结构。基本特点是线性表中的 数据元素有序且有限。结构中: ① 存在一个唯一的被称为“第一个”的数据元素; ② 存在一个唯一的被称为“最后一个”的数据元素; ③ 除第一个元素外,每

qq_47605698的博客 1450

C++ - 继承(inheritance) 和 动态绑定(dynamic binding) 简介

继承(inheritance) 和 动态绑定(dynamic binding) 简介 本文地址: http://blog.csdn.net/caroline_wendy/article/details/15646601 继承(inheritance)和动态绑定(dynamic binding) 是面向对象的重要组成部分, 即继承(inheritance)和多态...

weixin_34024034的博客 331

以高通camera 申请ion内存看dma-buf

1 fd 与ion buffer, file绑定 简单总结就是申请一个buffer,再创建一个dmabuf 结构体然后将,然后将dmabuf中得指针指向buffer,dmabuf 再传递给一个匿名的inode,获取到一个file,这样file和dmabuf绑定起来,也就和buffer关联上。然后再从进程中分配一个空闲的fd,将fd 和file囊绑定。这样就能通过fd 快速查找到buffer。file 是个全系统的,他和进程无关,但是fd 是每个进程都是自己独立的,所以再跨进程传输时只需要保证fd ...

兔兔里个花兔的博客 6444

C++侯捷学习笔记:关于Dynamic binding

C++侯捷学习笔记

yang_zw_1996的博客 789

State of GPT (ChatGPT 原理及现状介绍)

要用 RLHF 的一个简单的原因就是 RLHF 模型效果更好,下面的图来源于 InstructGPT 论文,PPO (RLHF 算法) 后的模型生成的答案更被人类喜欢。karpathy 认为 RLHF 有用的原因是判别比生成更容易,让标注员去写一些 SFT 的 QA 数据对是比较难的,如果有一个 SFT 模型生成一些数据让标注员判断哪个更好就简单很多。,GPT4 最强,前三个都是 RLHF 模型,其他模型都是 SFT 模型。伯克利做的模型评测榜单。

kebijuelun的博客 3578

基于Simulink进行光伏逆变器效率分析的仿真建模

特点能量转换:将光伏电池板产生的直流电转换为交流电。效率评估:分析逆变器在不同负载条件和环境条件下的效率。动态特性:考虑温度、光照强度等外部因素对逆变器效率的影响。挑战精确建模:准确地模拟光伏电池板、逆变器及其交互的动力学过程。多因素考量:需要同时考虑输入电压、电流、温度、光照强度等多种因素对逆变器效率的影响。集成度:需要与其他系统(如最大功率点跟踪MPPT算法、电网连接等)无缝集成,以实现全面的系统分析。首先明确要模拟的任务内容。输入条件(如光照强度、温度等)。

amy_mhd的博客 142

【C/C++ 基础知识 】C++中的静态绑定与动态绑定:深入解析与比较

绑定,简而言之,是将一个名称(如变量、函数等)与其所在的内存地址关联起来。这种关联可以在编译时(静态)或运行时(动态)确定。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 2005

8、对比 LightGBM、XGBoost 和深度学习

本文对比了LightGBM、XGBoost和深度学习模型(特别是TabTransformer)在处理表格数据时的性能差异。从模型复杂度、数据准备、训练时间、准确性和适用场景等方面进行分析,重点探讨了三者在人口普查收入预测任务中的表现。文章详细介绍了XGBoost与LightGBM的核心特性与区别,深入讲解了TabTransformer的架构与实现,并涵盖了分类特征编码、缺失值处理和类别不平衡等关键数据预处理技术,为选择合适的表格数据建模方法提供了实践指导。

julia4scientist的博客 120

Java中动态绑定(Dynamic Binding)和动态分派(Dynamic Dispatch)区别与联系

动态绑定是运行时选择方法实现的行为,而动态分派是实现动态绑定的核心机制之一。简单来说,动态分派是动态绑定的技术支持,二者是概念上的紧密关联。

开源AI 专属 UI——papyrai-ui。《千界明彻录》(故事形式构建元思维)——胡说小说。更多思辨内容在公众号。 671

YOLOv11涨点改进 | NeurIPS2025最佳论文!注意力改进篇| 引入Gated Attention门控注意力模块、太牛了!直接拯救了大模型的发展,助力目标检测、图像分割、图像分类有效涨点

本文提出了一种基于门控注意力机制(GatedAttention)的YOLOv11改进方法。该模块通过在标准注意力机制中引入头部特定的sigmoid门控,有效提升了模型性能和训练稳定性。实验表明,GatedAttention能够增强模型对关键信息的聚焦能力,减少无关区域关注,提高检测精度。同时,门控机制带来的非线性和稀疏性优化了计算效率,并缓解了训练不稳定性问题。文章详细介绍了模块原理、实现代码及三种改进方案配置方法,为YOLOv11在复杂场景下的目标检测提供了有效解决方案。

Ai缝合怪、助力小伙伴高效发论文 495

使用MATLAB结合EasySpin进行ESR模拟的详细步骤及示例代码

安装EasySpin:确保你已经安装了EasySpin工具箱,它可以帮助你进行ESR模拟。你可以从EasySpin的官方网站(https://easyspin.org/)下载并安装。准备实验数据:将实验得到的EPR数据整理成合适的格式,一般包含磁场(Magnetic Field)和信号强度(Intensity)两列。进行模拟:使用EasySpin的函数对单线态氧自由基和超氧自由基进行模拟。调整参数:通过调整模拟参数,使模拟得到的峰型和峰位置与实验数据尽可能匹配。导出数据。

AI的内部世界的博客 2005

如何理解C++中的动态绑定(dynamic binding)

    在浏览C++论坛时,我总是能发现很多C++初学者的提问帖子,都是关于动态绑定的。基本大意就是不完全理解动态绑定该如何理解,造成一些面试或者实际编程上的困扰。本文就是针对这个问题作出的解答。作者并非技术大牛,不当之处还请大家在评论中指出,在下万分感谢。    我对于C++动态绑定的理解,一句话,就是编译器用静态分析的方法加上虚拟函数的设计实现在程序运行时动态智能执行正确虚拟函数的技术。因

Sheen Space 6339

电商行业分析爬虫:抓取行业数据,进行行业分析

电商行业数据分析对于市场研究、竞争分析和商业决策至关重要。通过爬取电商平台的数据,我们可以深入了解市场动态、消费者行为和商品销售情况。本文将介绍如何构建一个电商行业分析爬虫,抓取商品信息、销售数据和用户评价等,并进行数据分析。

u014481728的博客 1628

解锁C++对象模型:Dynamic Binding深度探秘

Dynamic Binding(动态绑定)则是实现运行时多态的关键机制。在 C++ 中,当我们通过基类的指针或引用调用虚函数时,编译器不再在编译期确定具体调用哪个函数版本,而是在运行时根据指针或引用实际指向的对象类型来决定调用哪个派生类的虚函数实现 ,这就是动态绑定。例如,在一个图形绘制的项目中,我们有一个基类 “Shape”,以及派生类 “Circle” 和 “Rectangle”,它们都重写了基类的 “draw” 虚函数。当我们使用基类指针去调用 “draw” 函数时,运行时会根据指针实际指向的是 “C

大雨淅淅的博客 1252

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C++学习23、动态绑定与静态绑定

在C++编程中,绑定(Binding)是指将变量和函数名转换为地址的过程。根据绑定时机的不同,C++中的绑定可以分为静态绑定(Static Binding)和动态绑定(Dynamic Binding)。这两种绑定方式在编译和执行阶段的表现有所不同,对程序的效率和灵活性产生直接影响。本文将深入探讨C++中的静态绑定和动态绑定,并通过示例代码展示其具体应用。

HopeTTHappyXGC的博客 1399

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C#4.0 动态绑定(Dynamic Binding)

  .NET 4.0引入了一个新概念,叫动态绑定。所谓绑定,就是对类型、成员和操作的解析过程。动态绑定意味着与编译器无关,而与运行时有关。 一、 基本概念 C# 4.0之前的变量声明,在编译时已经决定其类型,虽然C# 3.0提供了var关键字来声明隐式类型,但用var声明的变量终究逃不过编译器的法眼。用dynamic声明变量的好处是,编译器在编译时并不知道它引用对象的确...

devo4561的博客 350

Java中的静态与动态绑定

在静态绑定中,编译器能够准确地确定要调用的方法或操作符,因为它们在编译时就已经决定了。在面向对象编程中,静态绑定(Static Binding)和动态绑定(Dynamic Binding)是Java中重要的概念。动态绑定是指在运行时根据对象的实际类型确定方法或操作符的调用版本。动态绑定通过Java的方法重写(Override)实现,适用于继承中的方法调用。静态绑定在编译时就能够确定调用的方法,因此具有更高的执行效率;而动态绑定允许程序在运行时根据对象的实际类型动态地选择调用的方法,提升了灵活性和多态性。

省赚客开发者博客 757

Objective-C中的@dynamic

Objective-C中的@dynamic   一、@dynamic与@synthesize的区别 @property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var;   @synthesize的语义是如果你没有手动实现setter方法和getter方法,

小树学信奥 5万+

集合类中泛型Integer与int的联系

先说结论:在集合类中,内置方法进行比较运算(如contains()、get())的时候,Integer等同于int。 集合类的泛型不允许使用基本数据类型,因此当我们需要使用int类型时往往会用Integer的泛型代替。这样,我们即可以向集合中添加Integer类型又可以添加int类型。我们知道,new不同Integer对象,以及-128~127范围外的Integer.valueOf()创建的对象都是不相等的,但在集合类中他们却相等。显然我们有必要通过源码了解一下集合类中对于这两种类型的处理。 事实上,集合类

qq_44375810的博客 1334

C++ dynamic binding

#include #include class Quote { public: virtual void sayHello() { std::cout << "Hello from base" << std::endl; } virtual void sayHi() { std::cout << "Hi from base" << std::endl; } virtual void sa

HelloWesh的专栏 922

dynamic binding

Late binding, ordynamic binding,[1]is a computer programming mechanism in which the method being called upon an object or the function being called with arguments is looked up by name atruntim...

diaoju3333的博客 226

Dynamic Binding

Dynamic Binding Dynamic binding is the process of mapping a message to a method at runtime, rather than at compile time. In effect, the message and the object receiving the message aren’t set until

chuanyituoku的专栏 978

Java中的多态(polymorphism)和动态绑定(dynamic binding)

以下面代码为例,存在超类Employee和子类Manager,两个类中都有getSalary方法,但实现不同。一个对象变量可以引用多种实际类型的现象被称为多态(polymorphism),运行时能够自动选择调用哪个方法的现象称为动态绑定(dynamic binding)。Employee类型的变量e既可以引用Employee类型又可以引用Manager类型,称为多态;调用e.getSalary时,根

lichengyu的专栏 4069

jersey利用filter和Dynamic binding来实现token拦截过滤请求

背景描述 做app后端服务的coder都知道,很多服务都是无状态的,所谓的无状态,在这里我们可以简单的理解为(与传统web不同点)没有session。 那么这个时候怎么保证我们的请求安全性呢(这里我们所提到的安全性即用户请求来源和判断的安全性,不涉及验签,加密等数据来源之类的安全)。 需求描述 我们要实现一个基于token令牌的请求拦截系统,针对我们的每一次的请求进行拦截。以此来判断用

Jerry的一亩三分地 2178

java中转型(upcasting)与动态绑定(dynamic binding)或者后期(late binding)细节

在Java中,父类与子类之间的类型转换有两种,一种是子类向上转型父类(这永远是安全的),另一种是父类向下转型为子类(这得由相应的instanceof来判断数据类型,同时这也是一种不安全的转换)Base class 与derived class 之间,为了达到从一个特定类型转为一个通用类型(有点多态的味道),可以借助向上]转型这一工具(即子类向上转为父类类型的),因为Java里的对象引用都是dy

提升自己-虚心钻研 2993
上一篇: 1. objC 动态类型(dynamic typing)
下一篇: 3. objC内存管理(<ios4.0)
恒哥的爸爸
博客等级 码龄21年 1056粉丝 70原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值