Objective-C中init函数实现的相关研究 if ((self = [super init]) != nil)

Objective-C与C语言关系解析:从语法到苹果开发生态 C语言作为编译型语言的代表,其语法结构和指针操作奠定了现代编程语言的基础。通过引入Smalltalk的消息传递机制,Objective-C在C语言之上构建了动态的面向对象模型,实现了运行时多态和动态绑定。这种设计使得Objective-C能够与C++代码混合编译,形成Objective-C++模式,为高性能计算和复用现有C++库提供了技术路径。在苹果开发生态中,这一技术价值体现在Cocoa框架的构建和Xcode工具链的深度整合上,使得开发者能够高效构建macOS和iOS应用。本文围绕C系语言谱系、Objec 阅读详情

 

 

/******************************************************************************

本文转载自优快云博客:http://blog.youkuaiyun.com/Cheng_Tian/archive/2010/07/16/5740831.aspx


 ******************************************************************************/

    今天在学习Objective-C时见到某初始化函数中有如下代码:

    self = [super init];

    if(self){

// Initialize members

    }

    return self;

    当时只是觉得Objective-C与才C++应该一样,每个子类对象都包含父类对象,所以super与self都是指向同一对象的头部的,[super init]返回的地址应该与self所代表的地址一样(即self == [super init])。那么,对self赋[super init]的值岂不是没有什么意义?

    找朱去讨论,他也不知道是因为什么。但是他想起了在《From C++ to Objective-C》中好像提到过这个情况,于是在一通查找之后终于在7.1.3(P25)找到了说明。那一节的例子中的对应代码是这样的:

    if(![super init])

return nil;

   // Initialize members

return self;

    同时下面又相应的说明:

    Polemic: Most people use the instruction self = [super init]; if (self) {...} in the initializer. This is justified by the fact that in some cases, [super init] could return a different object. However, in a very interesting document [6], Will Shipley shows that is a bad practice. It is far more logical to use the above form, where it is only checked whether [super init] returns nil or not.

    意思是很多人采用了self = [super init]; if (self) {...}的方法,这是由于有一些实践已经证明了[super init]有可能返回一个(与self所指对象)完全不同的对象。但作者推荐了一篇文章,说这篇文章证实了这个为大多数人所使用的初始化方式是一种不好的手法。

    这里所说的 a very interesting document[6] 指的是:

    [6] Will Shipley. self = [supid init]. http://wilshipley.com/blog/2005/07/self-stupid-init.html. 

    是一篇博文。在这篇博文里,作者对比了两种形式的初始化方法,它们是:

    1.Traditional -init

    - (id)init;

    {

if ((self = [super init]) == nil)

   return nil;

[...initialize my stuff...]

return self;

    }

    2.Wil's -init

    - (id)init;

    {

if (![super init])

   return nil;

[...initialize my stuff...]

return self;

    }

    作者认为不可能存在不用self = [super init]就不对的情况,所以他认为第二种方法才是正确的。他曾在以前的一篇博文上说谁能找到这样的情况就给那人20美元。

    但现在作者坦言这样的情况确实存在——一个名叫Ken Ferry的人编写了一个程序,该程序会自动为Cocoa库的每一个类派生出子类并产生程序将其实例化,并在初始化时判断[super init]是否返回的就是self。最终该程序Ken Ferry终于找到了一些这样的类——它们都是 single intance(单实例)的类。

    说到这里大家想必也都知道是怎么回事了,单实例的类初始化函数在第一次被调用时会返回新的实例,以后再被调用则只会返回第一次生成的实例。在这种情况下,作者提出的方式2也就有了问题 ——若遇到父类采用单例模式,则在子类中[super init]返回的确实非nil,但却也不再是子类对象所包含的那个父类对象了。如此一来子类对象所包含的那个父类对象并未被初始化,没有达到初始化函数的目的。

    但是我们也应该注意到第一种方式也是不对的——self被重新定向为指向父类那个单实例,如此一来则发生了内存泄露,因为self原先所指向的对象变成了“没有链子栓着的狗”(没有指针指向它)。

    原来两种方式都存在不足,那么该如何是好呢?作者提出了第三种方式:

    id superInitReturn = [super init];

    if(!superInitReturn || self != superInitReturn)

    {

return nil;

    }

    // Initialize memebers

    return self;

   我个人对此方法的理解是:若[super init]返回的与self不同,则说明父类是单实例类,而单实例类的init函数应该是被重写过的,一般会返回nil,遇到这种情况我们就该收手了——让你的类去继承一个单实例类并非好的设计(如果想达到类似效果,请让这个单实例成为你的类的成员)——故而返回nil。

    值得一提的是该博文为作者2005年所作,作者于2009年在末尾追加了更新,指出苹果公司有些说明表明了他们很有可能要重写[NSObject init]方法,主要是因为要采用新的内存管理手段以提高内存重用率,所以作者最终推荐的init方式为:

    -(id) init

    {

if(!(self = [super init]))

{

   return nil;

}

// Initialize members

return self;

    }

    原文如下:

    Update April, 2009:

There's been hints from Apple that they might modify the standard -[NSObject init] method to try to re-use old object's memory, since it turns out that a very common usage pattern is for programs to keep creating and deallocating, say, 12 objects of the same class, over and over. Re-using the exact same memory ends up being a big win (and this is a trick the iPhone already does with its UITableViewCell class, and that is a HUGE win if you do it yourself on the iPhone).

So, from now on, I recommend everyone uses:

Subclassing NSColorPanel the Right Way

- (id)init;

{

 if (!(self = [super init]))

   return nil;

 // other stuff

 return self;

}

I do.

    我还是感到不解,看不出他的理由是什么。明天继续研究,也希望有高手能来指点一二。

本文来自优快云博客,转载请标明出处:@"http://blog.youkuaiyun.com/Cheng_Tian/archive/2010/07/16/5740831.aspx"

 

 

LabView实现modbus通讯 labview实现modbus通讯 阅读详情

相关推荐

Ansys Lumerical 启动时出现 Error: Could not connect to Ansys license server specified at 1055@ 的一种解决办法

考虑到 2020 版的时候是直接在全局变量里指定具体地址,但是 2024 版本是写成 1055@localhost ,并且之后在站里搜相关 Ansys 的问题都指向 1055 端口被占用,虽然问题不一样,但是本着死马当活马医,就按照。我最近在跑超透镜结构,听说2024版本现在有GPU加速可以用,就把Lumerical从2020升到2024版本,结果发现一开头的破解办法完全不一样了。一开始安装的时候以为2020没有删干净,导致2024版的安装一直锁着目标地址,解决办法参考。的办法来操作,在关闭了。

qq_51404184的博客 5752

关于 objective - C 的 super init

[super init] 的结果可能有三种:   第一种: [super init] 初始化成功,这个是最最正常的情况。   第二种: [super init] 初始化失败,我们都知道oc的两步创建,alloc开辟内存空间,init初始化对象,但是init还有另外一个作用,在初始化失败的时候,init方法会返回一个nil。回头行文的最上面,如果self为nil,那么if(self)语句...

weixin_30325971的博客 204

基于YOLOX与LPRNet的车牌检测与识别系统(Python+UI界面)实战指南

本文详细介绍了如何利用YOLOX目标检测模型与LPRNet车牌识别模型,从零构建一个完整的车牌检测与识别系统。通过解析CCPD数据集、训练深度学习模型,并最终集成到PyQt5开发的图形化UI界面中,提供了一个从数据处理到应用部署的完整实战指南,帮助开发者快速掌握智能交通系统中的关键技术。

weixin_29230901的博客 337

回调 Objective-c 实现研究(未完成)

在计算机科学里, 回调(Callback)是指将一段可执行的代码以参数(面向对象程序里,也可以通过成员变量赋值的方式)的方式传递给目标代码。目标代码可以在需要的时刻(反向)调用传入的这段代码。   回调分为两种: 1. 同步回调(synchronous callbacks),又名阻塞回调(blocking callbacks)   2. 异步回调 (asynchronouscallbac

forceofwind的专栏 549

从零构建XVC协议栈:FPGA+W5300的跨界调试架构实战

本文详细介绍了如何从零构建XVC协议栈,通过FPGA与W5300以太网控制器的创新组合实现跨界调试架构。重点解析了JTAG时序逆向、TCP/IP协议栈集成与XVC协议实现,提供了硬件设计优化和性能加速技术,为嵌入式开发者和FPGA工程师提供实用的远程调试解决方案。

raspberrypi5的博客 247

Vienna整流器双PI闭环仿真:从SVPWM调制到中点电位平衡的实践解析

本文深入解析Vienna整流器双PI闭环仿真技术,涵盖SVPWM调制和中点电位平衡的实践细节。通过详细的MATLAB/Simulink仿真搭建流程和常见问题排查方法,帮助工程师掌握高效整流器控制策略,提升系统稳定性和动态响应性能。

weixin_29168153的博客 326

谈谈Objective-C下对象的初始化

众所周知,Objective-C是一门面向对象的语言,一般情况下,我们在Objective-C中定义一个类时,总要提供一个初始化方法,一般大家都是这样写的: - (MyClass *)init { self = [super init]; if (self) { //执行一些资源、变量的初始化工作 } return s

行者常至 3615

基于PWM的汽车仪表步进电机微步驱动优化实践

本文深入探讨了基于PWM的微步驱动技术,用于优化汽车仪表步进电机的运行性能。通过将传统的分步驱动升级为PWM微步细分驱动,利用正弦/余弦查表法合成旋转磁场,有效消除了指针抖动与噪声,实现了指针的平滑、精准运动。文章以STM32和VID2905电机为例,提供了详细的硬件连接、代码实现及高级优化技巧,为提升汽车仪表体验提供了实用方案。

weixin_29169505的博客 510

self = [super init]; if (self) { 与 if (self == [super init]) { 的理解

self = [super init];   if (self) {

lanceses的专栏 725

Python 爬虫实战:在房天下抓取房产信息,分析房价走势

通过本次 Python 爬虫实战,我们成功地从房天下爬取了房产信息,并进行了存储、处理、分析和可视化展示。在这个过程中,我们不仅掌握了爬虫技术的基本应用,还学会了如何对动态加载的数据进行处理和分析。然而,本次爬虫任务也存在一些局限性,例如仅爬取了部分区域的房产数据,且未对房产的图片和视频内容进行分析。在未来的工作中,我们可以进一步优化爬虫程序,爬取更多区域的房产数据,并深入分析房产的多媒体内容、用户行为模式等,为购房者和房地产从业者提供更有价值的数据支持。

u014481728的博客 1366

通过WorkVisual连接KUKA机器人的具体方法

通过WorkVisual连接KUKA机器人的具体方法

Robot_PLC_HMI_Automation 6842

Objective-C中init函数(self=[super init])实现的相关研究

今天在学习Objective-C时见到某初始化函数中有如下代码:     self = [super init];     if(self){ // Initialize members     }     return self;     当时只是觉得Objective-C与才C++应该一样,每个子类对象都包含父

Recording... 4164

Python 爬虫实战:抓取百科网站上某个词条的详细信息

百科网站(如维基百科)为用户提供了丰富的知识内容,涵盖了从历史、文化到科技等几乎所有领域的知识。对于需要大量数据进行分析、研究或机器学习项目的开发者而言,抓取这些网站的数据显得尤为重要。通过编写一个 Python 爬虫,我们能够轻松地抓取百科网站上的某个词条及其详细信息,从而获取并整理这些知识内容。本篇博客将深入介绍如何通过 Python 编写爬虫来抓取百科网站(如维基百科)的某个词条的详细信息,包括标题、正文内容、参考文献等。requests:发送 HTTP 请求,获取页面内容。

2201_76125261的博客 1669

self = [super init]

父类进行初始化时,用的是子类对象指针self,父类的init方法有可能对这个指针指向的内存区作了大的变更(有可能把这个指针所指的内存释放了,重新分配了另一块内存区域返回来,这时这个返回的指针与原来的指针是指向不同地址的),所以父类初始化后要重新返回指针。父类返回的和子类的self的类型都为id类型(通用类型)。父类的init方法若返回的指针与self不一样,在父类的init...

agcsdn2015的博客 77

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

self = [super init] 为什么要调用

初始化方法的标准结构是这样子的: - (instancetype)init { self = [super init]; // call the designated initializer if (self) { // Custom initialization } return self; } 我们主要来看看,这一句: s...

ITMan_K的博客 625

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

[iOS] 关于 self = [super init];

[iOS]关于self=[superinit]; 先看一下官方文档给出的初始化示例代码: [plain] view plaincopyprint? - (id)init { self = [super init]; // Call a designated initializer here. if (self != nil) { // 省略其他细节 } return self; } 容易让人困惑的地方在于,将父类初始化之后,将其返回的对象指针覆盖当前对象的指针。 这种方式令人...

Michae_8l的博客 208

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Objective-C语言的 if ( self = [super init] )什么意思?

nianqing8953  分类:其他编程语言 | 浏览 2112 次 Objective-C语言的 if ( self = [super init] )什么意思? 别和我说: 若要初始化子类就必须初始化父类什么的,书上网上全是这么说,我表示这样说我看不懂, 哪位高端娴熟程序员能仔细点给我指导下,谢谢了。 50分全部家当,全部送上. 分享到:

zhuhai__yizhi的专栏 995

Objective-C中init函数实现的相关研究

今天在学习Objective-C时见到某初始化函数中有如下代码: self = [super init]; if(self){        // Initialize members     } return self; 当时只是觉得Objective-C与C++应该一样,每个子类对象都包含父类对象,所以super与self都是指向同一对象的头部的,[super

Alex1226的专栏 485

Objective-C语言的 if ( self = [super init] )的理解

在初学OC开发时,对这段代码if(self = [super init])不甚理解,书上和网上说的是:若要初始化子类就必须初始化父类,但是为什么呢?让我们来一探究竟。 我们先假设现在自己创建了个类,我们起名叫MyObject,继承于NSObject。继承知道吧,就是你这个子类(MyObject)如果什么都不写的话,和父类(NSObject...

weixin_34279246的博客 178

对 self = [super init] 的理解

最近学习Objective-C,鉴于所有语言入门级讲解,对一些语法点讲解不够透彻,因此觉得有必要对一些语法点进行记录。 假如有两个类A,B,A继承于B,即A是B的派生类,对A进行初始化如下: A *a = [[A alloc] init]; 这行代码的含义是,类A产生一个对象,为对象分配内存(alloc),然后在调用 初始化方法。这是a指针的内存状态如下 self = [super

huariylee的博客 632

Objective-C方法重写:从运行时机制到iOS开发实战

方法重写是面向对象编程中实现多态性的核心技术,它允许子类重新定义父类的方法行为。其原理基于Objective-C的动态消息传递机制,运行时通过objc_msgSend函数在继承链中查找方法实现,实现动态绑定。这一机制为代码提供了强大的扩展性和灵活性,是构建复杂类层次结构的基石。在iOS开发中,方法重写广泛应用于自定义视图控制器生命周期、定制控件行为以及处理特定业务逻辑等场景。然而,不当的重写可能导致崩溃,例如未正确处理super调用、破坏KVO兼容性或与运行时机制冲突。本文通过一个游戏开发案例,系统解析了O

weixin_33724659的博客 484

[Obj-C笔记] "self = [super init]"的解释与潜藏bug

Objective-C的推荐init方法写法如下: - (id) init { if(self = [super init]) { //为子类增加属性进行初始化 } return self; } 这里涉及了几个问题, 1. [super init]的作用: 面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化。

qq315615051的博客 396

100天iOS数据结构与算法实战:Objective-C实现数据结构的5个最佳实践

**100天iOS数据结构与算法实战**是一个专注于Objective-C语言实现数据结构的开源项目,通过循序渐进的方式帮助开发者掌握iOS开发中必备的数据结构知识。本文将分享5个经过实战验证的最佳实践,帮助你编写出高效、可维护的Objective-C数据结构代码。 ## 1. 遵循面向对象设计原则封装数据结构 在Objective-C中实现数据结构时,首要原则是通过类封装内部实现细节。项目中

gitblog_00171的博客 1143
上一篇: dequeueReusableCellWithIdentifier
下一篇: MMS 协议学习笔记
iphoneing
博客等级 码龄16年 12粉丝 45原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值