iphone学习整理.docx
- 文档编号:7348687
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:16
- 大小:38.22KB
iphone学习整理.docx
《iphone学习整理.docx》由会员分享,可在线阅读,更多相关《iphone学习整理.docx(16页珍藏版)》请在冰豆网上搜索。
iphone学习整理
第一回
这是我在csdn的第一篇blog,想和大家分享我学习iphone开发的经验。
也希望借着写Blog来督促自己学习。
iphone使用objectivec作为其开发语言(apple真是屌啊,就他们家用objectivec吧。
。
),在学习iphonesdk之前,我们先看看objectivec的基本特点吧。
objectivec是一种c语言的变种,所以有时候在objectivec中能看到写c语言的影子。
objectivec和c的不同之处
1.objectivec使用nil来表示NULL2.objectivec用YESNO来表示truefalse3.objectivec用#import
在C++中,我们这样来调用方法:
aClass->function(var);但是在objectivec中,我们使用[aClassfunction:
var]objectivec中的消息(message)比较有意思的特点是:
1)调用消息的类可以不知道如何响应这个消息。
如果它不知道如何处理这个消息,它会自动的将这个消息转给其他的类,比如它的父类;2)调用消息的类可以是nil。
在C++中,在使用类方法之前,我们都需要检查对象是否为空,所以在实现析构函数的时候,常会有如下的代码,如if(var){deletevar;}但是在objectivec中,我们就可以直接写[varrelease];即使var==nil,也不会有问题。
照着老规矩,先写个helloworld#import
但是也不其然,objectivec是一个很好的面向对象的语言。
跟C还是有挺多不同之处。
我们先实现一个简单的类。
//Sample.h#import
NSObject{inta;}-(void)print;-(void)setA:
(int)a;@end咱们一句一句来看。
#import
objectivec声明类的格式如下:
@interfaceclassName:
baseClassName{membervariables;}memberfunctions@end大家可能注意到objectivec中函数的声明挺有特点的,我们现在来解释:
objectivec的函数声明的基本格式如下-/+(returntype)function_name;-/+(returntype)function_name:
(parametertype)parameter;-/+(returntype)function_name:
(parametertype)parameter1otherParameter:
(parameter_type)parameter2;1)-/+:
这个称做scope,如果在函数前面是-,那么理解为一般的函数;如果是+,可以理解为c++中的static函数2)函数的参数声明:
objectivec和c++,java都很不一样。
如果没有参数的话,在函数名后面,可以什么都不写;如果只有一个参数,在:
后面声明参数的类型和名称;如果有多个参数的话,每个参数前面都要有一个:
,然后接着是参数类型和参数名称。
可是大家可能还是觉得很奇怪。
比如上面这个例子中,otherParameter这个东西是干什么的呢?
在objectivec中,对于有多个参数的函数,我们可以理解为将函数的名称拆成了几个部分,每个部分都是对紧接着的参数的一个解释。
比如在C++中:
voidinitializeRectangle(intx1,inty1,intx2,inty2),但是我们并不知道这些参数都是什么意思;但是在objectivec中,我们可以这样声明:
voidinitializeRectangeWithLeftTopX:
(int)x1LeftTopY:
(int)y1RightBottomX:
(int)x2RightBottomY:
(int)y2;怎么样?
有感觉了吧。
下面来实现这个简单的Sample类//sample.m#import
(int)aa{a=aa;}@end使用这个类#import"Sample.h"intmain(intargc,char*argv[]){Sample*smp=[[Samplealloc]init];[smpsetA:
1];[smpprint];[smprelease];}在objectivec中,每一个类的对象都是一个指针,这和Java差不多(每个类的对象都用new声明)。
alloc类似于C中的malloc,init是NSObject中的方法,用于初始化这个对象。
如果我们实现了自己的初始化方法,也可以调用自己的初始化方法。
使用完毕后,需要调用release释放空间。
在iPhone开发中,需要特别注意内存的管理。
今后还会仔细些这部分的内容。
今天先写这么多。
未完待续:
)
第二回:
上次说了ObjectiveC是一种挺好的面向对象的语言。
那么我们今天就来看看ObjectiveC中的一些面向对象的特性吧。
构造函数(constructor)
其实我觉得在ObjectiveC中,这个名字并不算很恰当,可能叫做“初始化函数”比较合适一些吧。
因为这个函数其实就是一个普通的函数,和C++与Java中对构造函数的特殊待遇不同。
举个例子:
@interfaceSample:
NSObject{inta;}-(Sample*)initWithIntValue:
(int)aa;-(void)setA:
(int)aa;-(void)print;@end@implementationSample-(Sample*)initWithIntValue:
(int)aa{if(self=[superinit]){[selfsetA:
aa];}returnself;}//setA和print的实现参见上一篇@end其实,initWithIntValue就是所谓的“构造函数”。
我们在使用的时候,还是需要先调用父类NSObject中的alloc方法(注:
alloc方法是一个static的方法,它是被“+”修饰的,参见上篇关于函数声明的介绍):
Sample*smp=[[Samplealloc]initWithIntValue:
1];对构造函数的几个说明:
1)返回值一定要是类的指针2)一定要先调用父类NSObject的init函数,因为在ObjectiveC中所有的类都是从NSObject继承来的3)检查init返回的值是否有效4)self:
这是ObjectiveC的一个关键字,概念上和C++与Java中的this一样
访问限制
在面向对象程序设计中,大家一定很熟悉访问限制的概念,也就是C++和Java中的public,protected,private,在ObjectiveC中也有类似的东西#import
NSObject{@publicintpublicVar;@protectedintprotectedVar;@privateintprivateVar;}@end没错,就是挺简单的。
还记得之前说的ObjectiveC中的静态方法么(staticmessages)?
下面我们来看一个例子:
//ClassA.h#import
NSObject+(int)getCount;+(void)initialize;@end//Implementation@implementationClassA-(id)init{self=[superinit];count++;returnself;}+(int)getCount{returncount;}+(void)initialize{count=0;}@endstaticintcount;在C++中,还记得怎么声明静态变量么?
viewplaincopytoclipboardprint?
classA{public:
A();~A();protected:
staticinta;}staticintA:
:
a=0;classA{public:
A();~A();protected:
staticinta;}staticintA:
:
a=0;但是在ObjectiveC中,所谓类的静态变量其实可以理解为一个全局的静态变量,因为它并没有被放在@interface的定义里面。
接下来,getCount和initialize是两个静态方法。
getCount用于返回当前对象的个数,而initialize用于清空对象的计数。
但是在Implementation中,为什么会有init这个方法呢?
是的,这里可以理解为,我们重载了NSObject中的init方法:
仅增加了一个功能,就是计数。
我们不需要在头文件中声明init,因为我们继承了NSObject。
如何使用这个类呢:
intmain(intargc,char*argv[]){[ClassAinitialize];ClassA*c1=[[ClassAalloc]init];ClassA*c2=[[ClassAalloc]init];printf("ClassAcount:
%i\n",[ClassAgetCount]);......}读者自己试一试实现自己的release方法吧:
)未完待续~~
第三回
继承
我们接着来看objectivec中面向对象的特性。
要谈到面向对象,就不可能不说继承和多态。
其实,我们之前就已经谈到了继承,因为在objectivec中,所有类都是从NSObject继承而来的。
继承,可以理解为“is-a”的关系,这个概念相信对大部分人来说都在熟悉不过了,关于C++和Java的任何一本书都会详细介绍这个概念,这里我不再赘述,直接上例子。
//Rectangle.h#import
NSObject{intwidth,height;}-(Rectangle*)initWithWidth:
(int)wandHeight:
(int)h;-(void)setWidth:
(int)w;-(void)setHeight:
(int)h;-(void)setWidth:
(int)wandHeight:
(int)h;-(int)width;-(int)height;-(void)print;//printf("widthis%i,heightis%i\n",[selfwidth],[selfheight]);@end-(Rectangle*)initWithWidth:
(int)wandHeight:
(int)h和-(void)setWidth:
(int)wandHeight:
(int)h都是带多个参数的函数声明(参见第一篇)。
我们再实现一个正方形的类,继承矩形。
//Square.h#import"Rectangle.h"@interfaceSquare:
Rectangle{}-(Square*)initWithSize:
(int)s;-(void)setSize:
(int)s;-(int)size;@end//Square.m@implementationSquare-(Square*)initWithSize:
(int)s{if(self=[superinit]){[selfsetSize:
s];}returnself;}-(void)setSize:
(int)s{width=s;height=s;}-(int)size{returnwidth;}-(void)setWidth:
(int)w{[selfsetSize:
w];}-(void)setHeight:
(int)h{[selfsetSize:
h];}-(void)print{printf("thesizeis%i\n",[selfsize]);}@end上面这个正方形类,继承了矩形类的成员变量。
但是由于正方形的几何特殊性(长=宽),所以在正方形类中添加了三个方法。
分别是initWithSize,setSize,size。
另外,我们重载了矩形类中的setWidth和setHeight方法,因为正方形不允许分别设置长和宽。
如何使用:
intmain(intargc,char*argv[]){Rectangle*rect=[[Rectanglealloc]initWithWidth:
10andHeight:
5];Square*sq=[[Squarealloc]initWithSize:
10];[rectprint];[sqprint];[rectrelease];[sqrelease];}
虚函数
有了继承,我们就来说一说多态性。
C++中虚函数的概念相信大家都不陌生,它通过一个虚拟表(virtualtable)实现了动态绑定(dynamicbinding)。
在objectivec中也有类似的概念。
我们就以上面两个类为例子:
intmain(intargc,char*argv[]){Rectangle*rect=[[Rectanglealloc]initWithWidth:
10andHeight:
5];Square*sq=[[Squarealloc]initWithSize:
5];idshape;shape=rect;[shapeprint];//calltheRectangle'sprintshape=sq;[shapeprint];//calltheSquare'sprint......}这里,引入了objectivec的一个很重要的关键词id。
我们可以将id理解为C++中的void*,所以我们能将rect和sq都赋值给shape。
那么shape是怎么知道调用哪个版本的print的呢?
还记得第一篇中我们提到的message的概念么?
虽然id不知道如何响应print,但是它可以把这个消息传递给rect或者sq。
run-time的类类型检查
和c++与Java一样,objectivec也支持run-time的类类型检查-(BOOL)isKindOfClass:
classObj用于判断该对象是否属于某个类或者它的子类。
如:
if([sqisKindOfClass:
[Rectangleclass]]==YES){}-(BOOL)isMemberOfClass:
classObj用于判断该对象是否属于某个类(这里不包括子类)如:
if([sqisMemberOfClass:
[Rectangleclass]]==NO){}-(BOOL)respondsToSelector:
selector用于判断该对象是否能响应某个消息。
这里,我们可以将@selector后面带的参数理解为C++中的函数指针。
注意:
1)不要忘了@2)@selector后面用的是(),而不是[]。
3)要在消息名称后面跟:
,无论这个消息是否带参数。
如:
if([sqrespondsToSelector:
@selector(setSize:
)]==YES){}+(BOOL)instancesRespondToSelector:
selector用于判断该类是否能响应某个消息。
这是一个静态函数。
如:
if([SquareinstancesRespondToSelector:
@selector(setSize:
)]==YES){}我们之前说到Objective-C是一种很好的面向对象的语言,和C++和Java相比,Objective-C有一些自己独特的东西,下面我们来简单的介绍一下。
1)Category
回想一下,在C++中,如果我们想继承一个类,给它添加一些新的功能,我们需要什么?
当然是我们需要得到这个类的源代码。
但是在Objective-C中,由于有了这个Category的概念,我们可以在没有源代码的情况下,为一个已经存在的类添加一些新的功能,比如:
//DisplayMath.h@interfaceRectangle(Math)-(int)calculateArea;-(int)calculatePerimeter;@end//DisplayMath.m@implementationRectangle(Math)-(int)calculateArea{returnwidth*height;}-(int)calculatePerimeter{return2*(width+height)}@end这里,使用了之前定义的Rectangle类,我们想为它添加两个功能:
计算面积和周长。
即使没有Rectangle类的源代码,我们也可以通过Category创建Rectangle的子类。
使用Category的时候,需要注意两个地方:
1)只能添加新的方法,不能添加新的数据成员2)Category的名字必须是唯一的,比如这里,就不允许有第二个Math存在。
如何使用:
intmain(intargc,char*argv[]){Rectangle*rect=[[Rectanglealloc]initWithWidth:
5andHeight:
10];[rectcalculateArea];[rectrelease];}
2)如何创建私有方法
我们知道可以使用@private来声明私有变量,但是如何声明私有方法呢?
Objective-C中并没有什么关键词来修饰方法,如果我们想让某个方法不被其他的类所见,唯一的方法就是不让这个方法出现在头文件中。
比如:
//MyClass.h#import
是的,利用Category可以方便的实现“私有”方法。
3)Protocol
在Objective-C中,Protocol的概念很象Java中的interface或者C++中的virtualclass。
来看下面这个例子:
@protocolPrinting-(void)print;@end//MyDate.h@interfaceMyDate:
NSObject
(int)yandMonth:
(int)mandDay:
(int)d;@end//MyDate.m#import
(int)yandMonth:
(int)mandDay:
(int)d{year=y;month=m;day=d;}-(void)print{printf("%4d-%2d-%2d",year,month,day);}@end我们首先声明了Printing协议,任何遵守这个协议的类,都必须实现print方法。
在ObjectiveC中,我们通过<>来表示遵守某个协议。
当某个类声明要遵守某个协议之后,它就必须在.m文件中实现这个协议中的所有方法。
如何使用:
intmain(intargc,char*argv[]){MyDate*dat=[[MyDatealloc]init];[datinitDateWithYear:
1998andMonth:
09andDay:
01];id
@protocol(Printing)]==YES){}//true[datrelease];}注意两个地方:
1)使用id
iPhone程序开发时内存的管理
在开发iPhone程序时,一定要特别小心内存的管理。
其实基本的道理很简单,就像我们以前写C++程序一样,new和delete要成对出现。
问题是在某些时候,我们没有意识到自己使用了new。
Objective-C中对内存的管理采用引用计数的技术。
简单说就是,当我们拥有一个变量的时候,这个变量的计数就加1,当我们释放这个变量的时候,这个变量的计数就减1。
当计数为0时,这个变量就可以合法的被删除了。
1)alloc很明显,这个函数调用之后,变量的计数加1。
所以在调用alloc之后,一定要
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- iphone 学习 整理