由于昨天又光荣的去了车管所,导致没有更新,其次csdn得博客系统历时几年也终于更新了,不容易,不容易,除了变得更丑了加上功能更少了以外,没有发现又别的变化。
言归正传。今天来说一说objective-c 中类得一些独特得机制。
首先,需要说明得是合成存取器方法。这个功能其实在myecilpse中也又体现,比如一个vo或者po类,纯粹是为了在程序内部传递参数,将大量得数据封装到一个类里面,使用起来比较方便。而oc中在@interface 和 @end 标签中对定义的全局变量可以使用 @property 来让程序自动生成关于变量得存和取得方法。这是很让人激动得,可以生下来大量得代码。当在.h文件中定义了@property之后,就可以在接口得具体实现类中使用,@synthesize+全局变量名称,生成方法。之后就可以使用setX和getX之类得方法设置和获取变量得参数。
不得不说这确实是一个非常人性化得方法。
如果留意过之前得例子,就会发现oc中在调用类得成员方法会使用诸如以下得例子。
[MyClass methodName : value]
oc中同样也有使用点运算附访问类中成员方法得设置。形式如下:
MyClass.method=value;
但是这样就出现了一个问题,加入方法中得参数又很多,那么如何表示呢?
目前没有发现这样得例子,所以不如强制记忆成第一种方法。
当方法又多个参数时可以通过如下方法进行定义:
-(void) setTo:(int) n over:(int) d;
另外,在oc中,方法得参数其实时可以不使用诸如over或者setTo之类得方法名称得,但是为了程序的可读性,这种习惯还是保留下来比较好。
下面说说到底什么时局部变量,类变量和实例变量,java中变量分为以上三种,其中,局部变量的作用域仅仅存在于该类的方法中,当这个类的方法被调用的时候,局部变量才有生存的可能性,类变量是用static修饰的变量,这种变量在类中是可以随便使用的。最后是实例变量实例变量也在类中定义,但是不用static修饰。
self关键字,书中解释的十分抽象,原话是用来指明对象是当前方法的接受者。简单来说,就是在类中调用自己类中的方法。不需要在main方法中实例话对象之后分开调用方法,在类中就可以直接调用该方法。举个例子,比如说某类,通过方法分别实现了,接收三个参数,三个参数分别相加,三个参数和求平均值,可以选择在main中分别调用三个方法,获取三个参数,相加之后在求平均值。同时也可以,在获取和以后在求和方法中使用[self 求平均值],同样可以达到相同效果。
(其实说明的还是比较抽象的,因为假如说在一个类的实例化对象中需要调用这个实例对象的成员变量,如果从逻辑上分析是行不通的,因为每次调用都必须实例化出来一个本身的对象之后,才能对这个对象的变量进行操作,那么self就是解决这个问题的,当某个成员变量被self修饰以后,这个变量就能直接在被调用。java中只不过可以识别这些条件而已,但是现在感觉java的这种处理方法不是很符合oop的思想。)(2012.4.11)
下面着重讨论以下objective-c中垃圾处理的问题。
首先,为什么要垃圾处理?
正如前面用到的alloc命令一样,每一个oc中定义出来的变量或者类都需要向内存申请一个空间,用以储存和操作。但是,什么时候释放这些已经过期的内存呢?垃圾处理器就是负责这些工作的,当然,你也可以选择手动进行处理。其实,很多人在选择java的时候就是看重了java中强大的垃圾回收器的功能,这项伟大的发明,可以让程序员更专注于程序的编写,而不是永远都要担惊受怕于内存泄露的问题。传说中objective-c 2.0中已经引入了垃圾处理器的机制。
如何手动收回内存?
调用命令[Myclass release]就能收回该类的所占用的内存。
什么时候回收内存?
回收内存是一个很灵活的考虑,总体而言,就是在该类在一个周期中已经结束了他的任务,这个时候,我们就要在第一时间回收内存,以便给后续的操作流出更大的处理空间。说起来很简单,但是到底应该如何做呢?
下面是一个内存泄露的例子。
//*****code*****//
-(MyClass *) methodName: (MyClass*) m
//*****code*****//
int main(int argc,char* argv[])
{
//*****code*****//
MyClass *myclass1=[[MyClass alloc] init];
MyClass *myclass2=[[MyClass alloc] init];
MyClass *myclass;
myclass=[myclass1 mehtodName:myclass2];
[myclass1 release];
[myclass2 release];
[myclass release];
//*****code*****//
}
解释一下这个例子,有一个方法叫做methodName 里面进行了一些操作,进行这个操作需要向该方法中传入一个参数,这个参数是一个MyClass类型的参数,也就是要穿进去一个实例对象,同时在操作结束之后要返回一个MyClass参数。并且在main中调用了这些个方法,现在的问题是。在最后释放完内存以后,是否还会发生内存泄露呢?
事实上,确实会发生内存泄露,因为在[myclass1 methodName:myclass2]这个方法调用以后仅仅是将方法的返回值穿给了myclass但是该方法产生的这个对象我们并没有释放。所以就出现了内存泄露的问题,因为,在方法使用并传递参数之后该对象已经没有任何作用。但是不能释放,就造成了内存浪费。
所以说,应该如何解决这个问题呢?书山的原文是,将镶嵌的消息分成两个单独的消息。其实,我还是不明白- -
(其实现在我也不是很理解,在myclass1 调用了 methodName之后,确实会产生一个实例化对象,只不过这个对象是隐含的。而myclass只不过作为了一个容器接受了方法产生的对象,在这个过程中,方法产生了一个MyClass类的对象,这个对象在下面的release过程中被忽略了。从而导致了隐含的对象没有被释放。现在大概能明白书上的原文解释是什么意思,就是在方法产生对象的同时,给这个对象在内存中申请一个空间,然后再将这个空间中的值给myclass,在用完之后同时释放以上两个对象,就不会造成内存泄漏了)(2012.4.11)