转自:http://www.oschina.net/question/54100_32468

众所周知,Objective-C是一门面向对象的语言,一般情况下,我们在Objective-C中定义一个类时,总要提供一个初始化方法,一般大家都是这样写的:

- (MyClass *)init
{
self = [super init];
if (self) {
//执行一些资源、变量的初始化工作
}
return self;
}

这样一段简单的代码,却有很多可以思考的问题:

1、为什么要通过[super init]来调用父类的初始化方法,父类的初始化方法里又执行了什么东西?

首先,我们知道对象继承的概念,一个子类从父类继承,那么也要实现父类的所有功能,这就是is-a的关系,比如说狗是哺乳动物,那么狗必定具有哺乳动物的特征和功能。所以在子类的初始化方法中,必须首先调用父类的初始化方法,以实现父类相关资源的初始化。例如我们在初始化狗这一对象时,必须先初始化哺乳动物这一对象,并把结果赋予狗,以使狗满足属于哺乳动物这一特征。

典型的,在iOS下,所有的类都继承于NSObject,而NSObject的init方法很简单,就是return self。当父类的初始化完成之后,即self不为nil的情况下,就可以开始做子类的初始化了。

2、是否一定要提供初始化方法,是否一定要使用init作为初始化方法?

我们在Objective-C中创建一个对象通常使用

MyClass *newclass = [[MyClass alloc] init];

或者

MyClass *newclass = [Myclass new];

new方法是NSObject对象的一个静态方法,根据apple的文档,该方法实际上就是alloc和init方法的组合,实际上二者是一样的,但 apple还是推荐我们使用第一种方法,为什么呢?因为使用第一种方法,你可以使用自己定义的init方法来做一些初始化,当然,如果子类没有提供 init方法,自然调用的就是父类的init方法了。所以说,从安全性的角度来收,作为开发者我们在对象使用之前是一定要对对象进行初始化的,因此在定义类的时候一定要提供初始化方法。但是否一定要使用init作为方法名呢?答案是不一定。使用init作为方法名只是你重写了NSObject的init方法而已,如果你自己重新定义一个初始化方法,也是完全可以的,只要你在使用的时候记得调用新定义的初始化方法就可以了。

但是,这种方法从设计角度来看我觉得是不可取的。在可复用性方面会比较差,如果确有必要定义一些接受不同参数的初始化方法,我的建议是,先定义一个init的公用方法,再到其他方法中调用它,如:

- (id)init
{
self = [super init];
if (self) { }
return self;
} - (id)initWithString:(NSString *)aString
{
[self init];
self.name = aString;
} - (id)initWithImage:(UIImage *)aImage
{
[self init];
self.image = aImage;
}

补充:

在面向对象编程中,如果编写一个类而没有包含构造函数,这个类仍能编译并且完全可以正常使用。如果类没有提供显式的构造函数,编译器会提供一个默认的构造函数给你。除了创建对象本身,默认构造函数的唯一工作就是调用其超类的构造函数。在很多情况下,这个超类是语言框架的一部分,如java中的 Object类,objective-c 中的NSObject类。

不论是何种情况,在类中至少包含一个构造函数是一种很好的编程实践,如果类中有属性,好的实践往往是初始化这些属性。

——以上摘自《The Object-Oriented Thought Process》 by Matt Weisfeld

浅谈 Objective-C 下对象的初始化的更多相关文章

  1. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  2. 浅谈Windows环境下DOS及MS-DOS以及常见一些命令的介绍

    浅谈Windows环境下DOS及MS-DOS以及常见一些命令的介绍 前记 自己是搞编程的,首先我是一个菜鸟,接触计算机这么久了,感觉很多计算机方面的技术和知识朦朦胧胧.模模糊糊,貌似有些贻笑大方了:所 ...

  3. 浅谈Java中的对象和对象引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  4. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  5. (转)浅谈Java中的对象和对象引用

    原文地址: http://www.cnblogs.com/dolphin0520/p/3592498.html 在Java中,有一组名词经常一起出现,它们就是"对象和对象引用",很 ...

  6. 以用户注册功能模块为例浅谈MVC架构下的JavaWeb开发流程

    JavaWeb应用开发,撇开分布式不谈,只讨论一个功能服务应用的开发,无论是使用原生的Servlet/JSP方案,还是时下的SSM架构,都有一套经过工程实践考验的最佳实践,这综合考虑了团队协作.项目管 ...

  7. 浅谈BloomFilter【下】用Java实现BloomFilter

    通过前一篇文章的学习,对于 BloomFilter 的概念和原理.以及误报率等计算方法都一个理性的认识了. 在这里,我们将用 Java'实现一个简单的 BloomFilter . package pr ...

  8. GTK+浅谈之一Windows10下QtCreator中GTK+环境搭建(十几篇)

    一.简介 虽然GTK+是Linux下的开发环境,因为其跨平台特性,有时候需要在Windows上用到它的.如下是在Windows10下配置GTK+的开发环境.        Gnome的开发基础结构是围 ...

  9. 浅谈Java/Android下的注解

    什么是注解 java.lang.annotation,接口 Annotation,在JDK5.0及以后版本引入. 注解是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行相应的处理.通 ...

随机推荐

  1. linux之rootfs (UBIFS)

    转:http://www.360doc.com/content/11/1208/15/3700464_170655736.shtml 大大小小事情一堆,好久不更新了,这次记录下移植ubifs文件系统步 ...

  2. http请求及缓存框架 GalHttprequest

    GalHttprequest 是一个android平台上一个轻量级的http网络请求及缓存框架.当前GalHttpRequest支持以下功能: 同步请求Stirng.InputStream.Bitma ...

  3. appium+python自动化47-首次打开app权限弹窗问题

    前言 用真机运行appium代码,首次打开app有的手机会出现权限弹窗问题,一般这种弹窗都是在引导页前面或者引导页后面出现.权限弹窗上面的按钮都是固定的, 只需要定位到"始终允许" ...

  4. ylbtech-LanguageSamples-Delegates(委托)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Delegates(委托) 1.A,示例(Sample) 返回顶部 “委托”示例 本示例 ...

  5. RMAN备份与恢复之概念一

    1.  数据库完全备份: 按归档模式分为归档和非归档 归档模式 打开状态,属于非一致性备份 关闭状态,可以分为一致性和非一致性 非归档模式 打开状态,非一致性备份无效 关闭状态,一致性备份,非一致性备 ...

  6. 流畅的python第一章python数据模型学习记录

    python中有些特殊的方法,以双上下划线开头,并以双下划线结束的方法.如__getitem__,这些方法是特殊的方法,供python解释权内部使用,一般来说不需要调用 还有一种是以双下划线开头的,如 ...

  7. gridcontrol表头设置

    点击Run Disigner进入设计界面,设置颜色字体等信息在Appearance分支下面,设置行为功能,显示区域等在Options分支下面.

  8. 机器学习-Confusion Matrix混淆矩阵、ROC、AUC

    本文整理了关于机器学习分类问题的评价指标——Confusion Matrix.ROC.AUC的概念以及理解. 混淆矩阵 在机器学习领域中,混淆矩阵(confusion matrix)是一种评价分类模型 ...

  9. Linux 调度器发展简述

    引言 进程调度是操作系统的核心功能.调度器只是是调度过程中的一部分,进程调度是非常复杂的过程,需要多个系统协同工作完成.本文所关注的仅为调度器,它的主要工作是在所有 RUNNING 进程中选择最合适的 ...

  10. 再说rocketmq消息存储

    两篇精彩的文章: <RocketMQ源码 — 三. Producer消息发送过程> <RocketMQ源码解析:Message存储> rocketmq通过netty获取到消息请 ...