到目前为止,我们都使用的是下列方式创建对象
[类名 new];
这种new的方式,实际上是一种简化的方式。笔者在这里总结一下前面几章里面曾经提到过关于创建对象的2个步骤:
第一步是为对象分配内存也就是我们所说的allocetion,runtime会根据我们创建的类的信息来决定为对象分配多少内存。类的信息都保存在Class里面,runtime读取Class的信息,知道了各个实例变量的类型,大小,以及他们的在内存里面的位置偏移,就会很容易的计算出需要的内存的大小。分配内存完成之后,实际上对象里面的isa也就被初始化了,isa指向这个类的Class。类里面的各个实例变量,包括他们的超类里面的实例变量的值都设定为零。
需要注意的是,分配内存的时候,不需要给方法分配内存的,在程序模块整体执行的时候方法部分就作为代码段的内容被放到了内存当中。对象的内容被放到了数据段当中,编译好的方法的汇编代码被放到了代码段当中。在objecsive C里面,分配内存使用下列格式:
ID 对象名=[类名 alloc];
NSobjecs已经为我们提供了诸如计算内存空间大小以及初始化isa还有把各个实例变量清零,毫无疑问NSobjecs已经非常出色的完成了内存分配的工作,在一般情况下,我们不需要重写alloc方法。
第二步是要对内存进行初始化也就是我们所说的Initialization。 初始化指的是对实例变量的初始化。虽然在alloc方法里面已经把各个实例变量给清零了,但是在很多情况下,我们的实例变量不能是零(对于指针的实例变量而言,就是空指针)的,这样就需要我们对实例变量进行有意义的初始化。
按照objecsive-C的约定,当初始化的时候不需要参数的话,就直接使用init方法来初始化:
[对象名字 init];
init是一个定义在NSobjecs里面的一个方法,NSobjecs明显无法预测到派生类的实例变量是什么,所以同学们在自己的类里面需要重载一下init方法,在init方法里面把实例变量进行初始化。
但是,需要强调的是,由于某种原因我们的init也许失败了,比如说我们需要读取CNBLOGS.COM的某个RSS,用这个RSS来初始化我们的对象,但是由于用户的网络连接失败所以我们的init也许会失败,在手机应用当中的一些极端的情况下比如说有同学写一个读取网页内容的程序,在网页内容非常大的时候,那么alloc也有可能会失败,为了可以方便的捕获这些失败,所以我们在程序当中需要把上面的过程写在一起:
ID 对象名 = [[类名 alloc] init];
if (对象名)
加上了上面的if语句我们的初始化过程就是完美的,当然我们有的时候不需要这个if语句。当我们的alloc和init永远不会失败的时候。关于初始化的时候的错误捕获,笔者将在后面的章节里面论述。
为了我们写程序方便和简洁,在创建一个从NSobjecs派生的类的对象的时候,苹果公司把alloc和init简化成为new,我们在程序代码当中使用任何一种方式都是可以的,具体怎么写是同学们的喜好和自由。
到这里,有同学会问,如果我们的init需要参数怎么办?按照objecsive-C的约定,我们需要使用initWith...。也就是带参数的变量初始化,这个也是本章的主要内容。
本章在讲述initWith的同时,也将会顺便的给大家介绍一下实例变量的作用域。
7.1,本章程序的执行结果
在本章里面,我们将要继续使用我们在第4章已经构筑好的类cattle和Bull。从一般的面向对象的角度上来说,是不鼓励我们改写已经生效的代码的。但是本章的目的是为了使同学们可以很好的理解主题,所以笔者在这里暂时违反一下规则改写了一下cattle类,在里面追加了initWith方法,笔者也在cattle类里面追加了一些实例变量为了阐述实例变量的作用域的问题。由于在cattle类里面笔者追加了一些东西,所以在Bull类里面改写了saySomething这个函数,让我们的Bull可以说更多的内容。我们的redBull是这样说的:
图7-1,本章程序的执行结果
再次强调在实际的编程过程中,尤其是写大型程序多人合作的时候,除非发现BUG,否则不要改写已经生效的代码。这样会产生一些意想不到的结果,从而使其他的弟兄们或者姐妹们对你充满怨言。
总结以上是内存溢出为你收集整理的Objective-C 2.0 with Cocoa Foundation---对象的初始化以及实例变量的作用域(1)全部内容,希望文章能够帮你解决Objective-C 2.0 with Cocoa Foundation---对象的初始化以及实例变量的作用域(1)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)