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"

 

 

(11)(2.2.2) BLHeli32,AM32, and BLHeli_S ESCs(一) Ardupilot官网关于《Peripheral Hardware》的翻译 —《(2.2.2) BLHeli32,AM32, and BLHeli_S ESCs》。 阅读详情

相关推荐

PD虚拟机网络初始化失败的权限修复指南

本文针对Parallels Desktop虚拟机常见的“网络初始化失败”问题,提供了详细的权限修复指南。通过分析问题根源,指导用户安全备份并修改关键的`network.desktop.xml`和`dispatcher.desktop.xml`配置文件,以恢复PD虚拟机的网络连接。文章还包含了修复后的验证步骤及预防措施,帮助用户彻底解决并避免此类权限问题。

qqq44的博客 849

关于 objective - C 的 super init

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

weixin_30325971的博客 204

高通QCS2290 SecureBoot全流程实战:从密钥生成到NON-HLOS.bin生成

本文详细拆解了高通QCS2290平台SecureBoot安全启动技术的端到端实战流程。从开发环境搭建、RSA密钥对生成与证书链构建,到关键XML配置文件修改、固件编译与数字签名,最终完成NON-HLOS.bin集成打包,为嵌入式开发者提供了一份清晰、可操作的安全启动部署指南。

weixin_28273593的博客 298

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

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

forceofwind的专栏 549

从Jira到Notion:用Sequential Thinking重构你的敏捷工作流(含GPT-6配置模板)

本文探讨了如何利用Sequential Thinking这一AI认知模型,重构敏捷开发工作流。通过连接Jira、Notion等工具,构建动态依赖图谱,实现从被动响应到主动规划的转变。文章提供了详细的配置教程和GPT-6配置模板,帮助团队实现任务自动拆解、智能看板生成与跨平台协调,从而提升项目管理效率。

gpt4scribbler的博客 204

C语言设计模式全面解析:从理论到28个实战示例

本文系统介绍了23种经典设计模式在C语言中的实现方法。通过结构体、函数指针等技巧,C语言可以优雅地模拟面向对象特性,实现代码复用与解耦。文章分类详解了创建型、结构型、行为型三大类模式,并提供了28个完整代码示例,包括单例、策略、观察者等核心模式的精简实现。这些模式在嵌入式系统、操作系统内核等场景中广泛应用,如状态机、事件驱动等。学习C语言设计模式的关键在于理解模式意图,掌握函数指针和结构体组合等技巧,并在实际项目中灵活运用。本文为C语言开发者提供了全面的设计模式参考指南。

数字人生 362

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

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

行者常至 3615

【Claude Code 源码解析教程】第4章:QueryEngine 查询引擎

本章深入解析 Claude Code 的核心引擎——QueryEngine,它是整个对话系统的"心脏",负责管理会话状态、消息处理流程和多轮对话支持。

rengang66的博客 269

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

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

lanceses的专栏 725

【赛题解析&命令脚本配置】2024年第十七届山东省技能大赛 | 网络系统管理”赛项-模块B:Linux服务部署 & ⑤客户端OutsideCli和InsideCli工作任务

【赛题解析&命令脚本配置】2024年第十七届山东省技能大赛 | 网络系统管理”赛项-模块B:Linux服务部署 & ⑤客户端OutsideCli和InsideCli工作任务 | 【赛题解析&命令脚本配置】2024年第十七届山东省技能大赛 | 网络系统管理”赛项-模块B:Linux服务部署 & ⑤客户端OutsideCli和InsideCli工作任务

君逍遥o 317

从生产订单到整车交付,SAP 离散制造在汽车行业里的真实落点

汽车行业谈数字化,很容易一上来就谈智能工厂、数字孪生、AI 排产、无人仓、视觉质检。可落到 SAP 项目现场,真正把工厂撑起来的,往往还是几个很朴素的问题,客户订单来了以后,BOM 能不能准确展开,物料能不能准时到线,产能有没有被过度承诺,生产订单能不能被车间正确执行,质量问题能不能追溯,成本能不能按工单和批次沉淀下来。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 113

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

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

Recording... 4164

最强游戏投屏串流搭档Sunshine+Moonlight配置方法

因祸得福的是,sunshine作为开源的self-host的服务端,不仅可以代替Novidia的服务端角色,还拓展了moonlight可以服务的主机,非novidia显卡的PC也可以通过这对搭档实现高质量的游戏窜流投屏了。回到moonlight,点击电脑图表,会给你一个Pincode,到Sunshine控制台,菜单点击Pin,输入moonlight给出的pin码。高质量的图像: Moonlight支持高清(HD)和甚至4K分辨率的投屏,同时还提供了对音频的传输支持,确保用户可以享受到高质量的视频和音频。

每日出拳老爷子的博客 1万+

self = [super init]

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

agcsdn2015的博客 77

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

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

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

ITMan_K的博客 625

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

[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

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

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、付费专栏及课程。

余额充值