初识化知识

1、Cocoa对象的创建

我们都知道创建一个对象有两步:alloc和init(对象分配和初始化),两步缺一不可。初始化一般都是紧接着对象分配的后面进行,但是这两个操作的作用是完全不同的。

分配对象:就是Cocoa从应用程序的虚拟内存中为对象分配一块内存。Cocoa会根据对象的实例变量(类型和变量的排列顺序)计算内存大小并分配内存。为了分配内存,你需要向类对象(类对象上篇详细讲了它的由来和作用)发送alloc或者allocWithZone:发送消息。消息返回一个未初始化的类实例。那发送分配消息除了分配内存外,还做了其他的一些很重要的工作:

对象的保持(retain)数设置为1.

分配的对象的isa指针指向类对象。

把对象所有的实例变量初始化为0.也可以理解成0的等价类型:nilNULL

这样所有的对象都有了isa指针,而且指向它们对应的类对象,这样对象就可以找到它运行时的信息。比如对象在继承层次机构上所在的位置(哪个是父类,哪个是子类等信息),它实现的协议,还有能响应什么消息。

即便如此,alloc之后的对象还不是一个可用的对象,对象必须初始化。

1.1初始化对象

初始化过程就是把对象的实例变量设置成有效合理的值,或者说你想要的数据。如果你的类没有实现初始化方法,它会调用父类的。

初始化方法的形式

初始化方法是实例方法,返回的是id类型的对象。初始化方法是讲究形式的,不能乱写。方法你可以有参数,多个也行,但是必须是init开头,比如:

-(id)initWithArray:(NSArray*)array;(fromNSSet)

参数形式:WithType:

初始化的问题

初始化也有问题?啥问题!?有时候初始化返回的并不是一个新的对象。什么时候呢?比如:我们熟悉的单例模式的时候。还有保持对象某个属性唯一的时候。账户类的id唯一性,如果初始化一个id是已存在的id,那就要返回已存在id对应的账户对象。

这时候我们需要:

释放刚刚分配的对象(是不是感觉很浪费,刚分配了又要释放,都没用了呢,没办法的事情啊)

返回已存在的账户对象

有时候你初始化对象失败了,也需要有一些操作。怎么会失败呢?比如:initFromFile:这个初始化方法,它是要从一个文件初始化,万一这个文件不存在,那就是初始化失败,初始化失败了怎么办:

释放刚刚分配的对象

返回nil

对象不能重复初始化,不然会产生NSInvalidArgumentException异常。

实现初始化方法

自定义类可能就需要自己写初始化的方法了,可以有一个或多个初始化方法,看你设计的类的需要。不过实现初始化方法需要遵循以下步骤:

先要调用父类的初始化方法

检查父类初始化返回的对象,如果是nil则初始化失败,也返回nil

在初始化实例变量时,如果它们是其他对象的引用,必要时要进行retain和copy

如果返回一个已存在的对象,那首先释放新分配的对象(刚才提到的账号的类)

遇到问题初始化不成功(比如初始化文件失败),返回nil

如果没有问题,返回self。初始化完成

下面这个例子能说明这几个步骤,请看:

注意:子类初始化时,必须先调用父类的初始化方法,以保证继承链中父类的实例变量得到正确的赋值。

下图解释继承链的初始化过程

1.2dealloc方法

dealloc和init方法是相呼应的。dealloc确保的是对象的实例变量和动态分配的内存被正确的释放。和init方法相反,父类的dealloc是在释放了其他的之后最后调用的。

1.3工厂类方法

工厂类方法把分配对象和初始化合二为一,返回创建对象,而且还自动释放。这些方法的形式一般是:+(type)className...

NSDate工厂类方法:

打印出来now:2012-10-2306:39:25+0000

引当前时间为基准,0是当前时间,+0000表示是时区,咱们是8时区,+8是14:39。如果参数是24*60*60是明天的时间,如果是负数那就是昨天的时间。

2、运行时内省的能力

内省(Introspection)是面向对象语言和环境的重要特性,Objective-C和Cocoa在这方面做的很好。内省是对象自己检查自己做为运行时对象详细信息的一种能力。这些详细信息包括对象在继承树上的位置,对象是否遵循特定的协议,以及是否可以响应特定的消息。NSObject协议和类定义了很多内省方法,用于查询运行时信息,以便根据对象的特征进行识别。

灵活的使用内省能力可以让你的程序更稳定强大。内省可以避免错误地进行消息派发、对象相等的错误判断等问题。下面介绍内省的一些实用方法:

2.1定位继承关系

NSObject协议声明了几个方法,用于确定对象在类层次中的位置。class返回类的Class对象。superclass返回父类的Class对象。看下面例子:

返回的两个Class对象看是否相等。

检查类对象的从属关系:isKindOfClass:判断是否是这个类的或这个类的子类的实例。isMemberOfClass:这个更严格些,判断是否是这个类的实例。例子:

2.2判断方法的实现或者是否遵循某个协议

NSObject还有两个功能更加强大的内省方法,即respondsToSelector:和conformsToProtocol:。两个是实例方法。respondsToSelector判读对象是否实现某个的方法,conformsToProtocol判断是否遵循指定的正式协议(正是协议的意思是实现该协议的所有方法)。所有继承NSObject的类都有有这两个方法。

respondsToSelector例子:

2.3对象的比较

hash和isEqual:方法都在NSObject协议中声明,且彼此关系紧密。实现hash方法会返回一个整型数。两个对象相等意味着它们有相同的哈希值。如果您的对象可能被包含在象NSSet这样的集合中,则需要定义hash方法,并确保该方法在两个对象相等的时候返回相同的哈希值。不过NSObject类中缺省的isEqual实现只是简单地检查指针是否相等。

isEqual方法例子:

如果子类增加了实例变量,比较子类需要对子类的实例变量也做比较才能确定对象是否相等时,需要重载isEqual方法:

3、对象可变性(mutable)

3.1为什么要有可变与不可变对象

创建对象的时候,选可变的对象还是选不可变的对象呢?怎么决定呢。先看看为什么要有可变与不可变这两种对象的存在。

可变的对象的类前面都有Mutable的关键字,这些类有:

NSMutableArray
NSMutableDictionary
NSMutableSet
NSMutableIndexSet
NSMutableCharacterSet
NSMutableData
NSMutableString
NSMutableAttributedString
NSMutableURLRequest

它们都是对应的不可变类的子类。

如果对象都是可变的,那在某些场景中是很不安全和不可靠的。比如你的某个对象当做参数传给了某个方法,你不希望你的对象被改变。这时这个方法却你的变量改变了,这是你不想要的结果。而在另外一些场景却相反。OK,为了对应不同的场景,对象就必须有可变与不可变之分了。

3.2什么时候用可变对象

当需要在对象创建之后频繁或不断地对其内容进行修改时,请使用可变对象

有些时候,用一个不可变对象取代另一个可能更好。比如,大多数保留字符串的实例变量都应该被赋值为一个不可变的NSString对象,而这些对象则用“setter”方法来进行替换。

依靠返回类型来进行可变性提示。

如果你不能确定一个对象是可变的,则将它当成不可变的处理。

初识化知识

时间: 2024-08-01 13:21:44

初识化知识的相关文章

知乎-长期接收碎片化知识有什么弊端?

你所接受的一切信息,构成了你的思维方式. 所以,长期接受碎片信息的后果,就是让你的思维变得狭隘,难以进行复杂的思考. ? 碎片信息通常具备这样的特征: ?它们往往是一些事实的集合而非逻辑 ?它们往往大量简化了推演过程 ?它们往往将多路径简化为单一路径 ?它们往往不够严谨.全面 ? 简而言之,碎片信息为了达到易于习得的目的,通常会显著降低认知成本,最明显的方式就是:将复杂的事物简单化.它们往往只告诉你表面上的东西,却不会告诉你背后的原理,以及它与其他事物之间的联系. ? 我们所说的「知识」,由两部

插件化知识详细分解及原理 之代理,hook,反射

上一篇我们说了Binder机制,通过aidl的demo和系统源码的对比进行了运行过程的分析,这一篇我们说代理模式及反射,之前说过了,只是为了梳理插件化需要了解的知识点,所以不会特别深的去讲解. 代理模式: 也叫做委托模式,分为静态代理和动态代理.代理模式也是平时比较常用的设计模式之一,代理模式有代码简洁,高扩展性的特性.主要目的就是为访问者提供一个代理,以达到限制某个对象的访问,也就是说想访问一个对象,其实我给你的是一个代理,不让你直接使用我.估计不理解的人会问为什么使用代理模式,他限制了对象的

CCNA学习笔记(一)--初识网络知识

在这里主要是多谢  闫辉.红茶三杯二位大神的无私奉献!!!  CCNA(Cisco Certified Network Associate)这个只是cisco的基础,不过我们有空时还是要去认识它下,免得到时用到时,一头迷糊!!别的不多说,直接奔主题吧. 这章我们主要了解的内容有: 1.网络基础: A.首先我们来认识下网络中使用的相关设备图标. 由上图我们知道CISCO中要使用到的设备名了,但这些只是在图纸上面显示吧了,现实是其实不是这样的.所以有机会一定还是要使用真机来操作. 下图为真机 B.什

初识JSP知识

一.jsp概述 JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP实际上就是Servlet. jsp = html + java html:静态内容 servlet:服务器端的小应用程序.适合编写java逻辑代码. jsp:适合编写输出动态内容,但不适合编写java逻辑. 二.jsp的原理 jsp页面通过服务器的翻译 ---〉变成java文件通过编译 ---〉变成class文件用来执行 jsp文件是用来做显示模

碎片化知识整理

@property (strong,nonatomic)NSMutableArray *cards; @end @implementation Deck -(NSMutableArray *)cards { if (!_cards){_cards=[[NSMutableArray alloc]init]; } return _cards; } 惰性初始化 惰性初始能提高内存使用效率 -(void)addCard:(Card *)card atTop:(BOOL)atTop { if (atTop

乱七八糟记一下乱七八糟的碎片化知识

一.GitHub二次上传顺序 检查分支,确定分支 提交到缓冲区                              git add 将缓冲区内容提交到本地仓库     git commit -m 描述上传内容 推送到远程仓库                           git push 原文地址:https://www.cnblogs.com/xyJen/p/11210718.html

长期通过微博、微信、知乎等平台接收碎片化的知识有什么弊端?

"碎片化"是移动互联网时代的大势,虽说一方面可以将这样的趋势理解做"合理运用时间".然而长期接受碎片信息的后果也是有弊端的,即碎片化的信息极其容易被我们遗忘.你以为你得到了很多,但其实你什么都没有得到.希望今天分享的文章对同样碎片化的你们有些用. 分享人:张颖 作   者:Lachel (知乎) 你所接受的一切信息,构成了你的思维方式. 所以,长期接受碎片信息的后果,就是让你的思维变得狭隘,难以进行复杂的思考. 1.碎片信息通常具备这样的特征: 它们往往是一些事实的

2015第43周五知识分享会

晚上去青年路参加了wiz笔记主办的知识分享会,感觉里面的很多知识观点自己都懂都知道,但是如果要自己去讲也未必有晚上分享者讲的好,其实最主要的还是多讲故事,结合可视化的图文讲故事,最好能讲自己的经历故事,实在讲不出自己的故事,就讲自己听了的哪些生动有趣好玩的故事. 通过装修谈学习力的切入点很好,但感觉讲的太浅,其实就讲几点结构化知识,从书和知乎上获取高质量的信息,向内行一样提问. 知识的修炼重点就是讲搜集.整理.思考.实践分享的过程,纵向目录维度和横向标签维度,努力将数据变成信息再变成知识,最终沉

长期接受碎片化信息,会有什么后果?

长期接受碎片化信息,会有什么后果? 你所接受的一切信息,构成了你的思维方式.所以,长期接受碎片信息的后果,就是让你的思维变得狭隘,难以进行复杂的思考. 碎片信息通常具备这样的特征: 它们往往是一些事实的集合而非逻辑 它们往往大量简化了推演过程 它们往往将多路径简化为单一路径 它们往往不够严谨.全面 简而言之,碎片信息为了达到易于习得的目的,通常会显著降低认知成本,最明显的方式就是:将复杂的事物简单化.它们往往只告诉你表面上的东西,却不会告诉你背后的原理,以及它与其他事物之间的联系. 我们所说的"