



版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Objective-C代码学习大纲(1)2011-05-1114:06佚名otierney我要评论(4)字号:TT
收藏本文为台湾出版的《Objective-C学习大纲》的翻译文档,系统介绍了Objective-C代码,很多名词为台湾同胞特指词汇,在学习时仔细研读才能体会。AD:2013大数据全球技术峰会低价抢票中所有这篇初学者指南的源始码都可以由objc.tar.gz下载。这篇教学中的许多範例都是由SteveKochan在ProgramminginObjective-C.ー书中撰写。如果你想得到更多详细资讯及範例,请直接参考该书。这个网站上登载的所有範例皆经过他的允许,所以请勿复製转载。设定环境Linux/FreeBSD:安装GNUStep为了编译GNUstep应用程式,必须先执行位于/usr/GNUstep/System/Makefiles/GNUstep.sh的GNUstep.sh这个档案。这个路径取决于你的系统环境,有些是在/usr,some/usr/lib,有些是/usr/localo如果你的shell是以csh/tcsh为基础的shell,则应该改用GNUStep.csho建议把这个指令放在.bashrc或,cshrc中。MacOSX:安装XCodeWindowsNT5.X:安装cygwin或mingw»然后安装GNUStep
前百这篇教学假设你已经有一些基本的c语言知识,包括C资料型别、什么是函式、什么是回传值、关于指标的知识以及基本的C语言记忆体管理。如果您没有这些背景知识,我非常建议你读ー读K&R的书:TheCProgrammingLanguage(译注:台湾出版书名为C程式语言第二版)这是C语言的设计者所写的书。Objective-C»是C的衍生语言,继承了所有C语言的特性。是有一些例外,但是它们不是继承于C的语言特性本身。nil:在C/C++你或许曾使用过NULL,而在Objective-C中则是nil。不同之处是你可以传递讯息给nil(例如[nilmessage];)»这是完全合法的,然而你却不能对NULL如法炮製。BOOL:C没有正式的布林型别,而在Objective-C中也不是「真的」有。它是包含在Foundationclasses(基本类别库)中(即importNSObject.h;nil也是包括在这个标头档内)。BOOL在Objective-C中有两种型态:YES或N0,而不是TRUE或FALSE〇#importvsttinclude:就如同你在helloworld範例中看到的,我们使用了#importoftimport由gcc编译器支援。我并不建议使用ttinclude,#import基本上跟,h档头尾的ttifndef#define#endif相同。许多程式员们都同意,使用这些东西这是十分愚蠢的。无论如何,使用#timport就对了。这样不但可以避免麻烦,而且万一有一天gcc把它拿掉了,将会有足够的Objective-C程式员可以坚持保留它或是将它放冋来。偷偷告诉你,Apple在它们官方的程式码中也使用了#importB所以万一有一天这种事真的发生,不难预料Apple将会提供ー个支援ftimport的gcc分支版本。在Objective-C中,method及message这两个字是可以互换的。不过messages拥有特别的特性,ー个message可以动态的转送给另ー个物件。在Objective-C中,嗯叫物件上的ー个讯息并不一定表示物件真的会实作这个讯息,而是物件知道如何以某种方式去实作它,或是转送给知道如何实作的物件。编译helloworldhello.m#main(intargcrconstchar*argv[]){.printf("hell〇world\nn);.return0;}输出helloworld在Objective-C中使用#import代替#includeObjective-C的预设副档名是.m
Objective-C代码学习大纲(2)2011-05-1114:06佚名otierney我要评论(4)字号:TT
收藏Q本文为台湾出版的《Objective-C学习大纲》的翻译文档,系统介绍了Objective-C代码,很多名词为台湾同胞特指词汇,在学习时仔细研读才能体会。AD:2013大数据全球技术峰会低价抢票中创建classes©interface..Fraction.h.#import.@interfaceFraction:NSObject{.intnumerator;intdenominator;}. -(void)print;--(void)setNumerator:(int)n;-(void)setDenominator:(int)d;-(int)numerator;. -(int)denominator;.@endNSObject:NeXTStepObject的缩写。因为它已经改名为OpenStep,所以这在今天已经不是那么有意义了。继承(inheritance)以Class:Parent表示,就像上面的Fraction:NSObject〇夹在@interfaceClass:Parent{....}中的称为instancevariableso没有设定存取权限(protected,public,private)时,预设的存取权限为protectedo设定权限的方式将在稍后说明。Instancemethods跟在成员变数(即instancevariables)后。格式为:scope(returnType)methodName:(parameterIType)parameterIName;scope有class或instance两种。1nstancemethods以ー开头,classlevelmethods以+开头。Interface以一・个@end作为结束。©implementation.Fraction.m.
#import@implementationFraction(void)print{. printf(n%i/%iM,numeratorrdenominator);TOC\o"1-5"\h\z). -(void)setNumerator: (int) n {. nnumerator=n;. }. -(void)setDenominator: (int) d{. ddenominator=d;}. -(int) denominator {. return denominator;. }. "(int) numerator {. return numerator;). @endImplementation以©implementationClassName开始,以@end结束。Implementation以4..9.101112131415161718192021222324252627282930313233343536373839Implement定义好的methods的方式,跟在interface中宣告时很近似。把它们凑在ー起main.m.#import..#importnFraction.hintmain(intargc,constchar*argv[]){//createanewinstanceinit];Fraction*fracinit];//setthevalues.[fracsetNumerator:1];[fracsetDenominator:3];//printitprintf("Thefractionis:”);[fracprint];.. printf(“ヽn");//freememory[fracrelease];return0;}outputThefractionis:1/33.Fraction*frac[[Fractionalloc]init];这行程式码中有很多重要的东西。在Objective-C中惣叫methods的方法是[objectmethod],就像C++的object-〉method()。Objective-C没有value型别。所以没有像C++的Fractionfrac;frac.print():这类的东西。在Objective-C中完全使用指标来处理物件。这行程式码实际上做了两件事:[Fractionalloc]嗯叫了Fractionclass的allocmethodo这就像malloc记忆体,这个动作也做了一样的事情。[objectinit]是ー个建构子(constructor)惣叫,负责初始化物件中的所有变数。它惣叫了[Fractionalloc]传回的instance上的initmethodo这个动作非常普遍,所以通常以一行程式完成:Object*var=[[Objectalloc]init];[fracsetNumerator:1]非常简单。它嗯叫了frac上的setNumeratormethod并传入1为参数。如同每个C的变体,Objective-C也有一个用以释放记忆体的方式:releaseo它继承自NSObject,这个method在之后会有详尽的解说。Objective-C代码学习大纲(3)2011-05-1114:06佚名otierney我要评论(4)字号:TT本文为台湾出版的《Objective-C学习大纲》的翻译文档,系统介绍了Objective-C代码,很多名词为台湾同胞特指词汇,在学习时仔细研读才能体会。AD:2013大数据全球技术峰会低价抢票中详细说明...多重参数目前为止我还没展示如何传递多个参数。这个语法乍看之下不是很直觉,不过它却是来自一个十分受欢迎的Smalltalk版本。Fraction,h.....-(void)setNumerator:(int)nandDenominator:(int)d;.....Fraction.m・・.. -(void)setNumerator:(int)nandDenominator:(int)d{. nnumerator=n;. ddenominator=d;}.... main.m.#import
2627282930313233343536373839404142434445464748495051525354555657585960616263646566676869♦import"Fraction.hnintmain(intargc,constchar*argv[]){//createanewinstanceFraction*frac=[[Fractionalloc]init];Fraction*frac2=[[Fractionalloc]init];//setthevalues[fracsetNumerator:1];[fracsetDenominator:3];//combinedset[frac2setNumerator:1andDenominator:5];//printitprintf("Thefractionis:");[fracprint];printf("\n");//printitprintf("Fraction2is:");[frac2print];printf("\n");//freememory[fracrelease];[frac2release];return0;
}outputThefractionis:1/3.Fraction2is:1/5这个method实际上叫做setNumerator:andDenominator:加入其他参数的方法就跟加入第二个时一样,即method:label1:label2:label3:,而惣叫的方法是[objmethod:param1label1:param2label2:param3label3:param4]Labels是非必要的,所以可以有一个像这样的method:method:::,简单的省略label名称,但以:区隔参数。并不建议这样使用。建构子(Constructors)!,Fraction.h.......-(Fraction*)initWithNumerator:(int)ndenominator:(int)d;.フ・・・・.Fraction.m・・.. -(Fraction*)initWithNumerator:(int)ndenominator:(int)d{.self[superinit]self[superinit];
17.18.if(self){19.20.[selfsetNumerator:nandDenominator:d];21.22.}23.24.returnself;25.26.}27.28.•♦•29.30.main.m31.32.#import33.34.♦importnFraction.h,main(intargc,constchar*argv[]){37.38.//createanewinstance39.40.Fraction*frac=[[Fractionalloc]init];41.42.Fraction*frac2=[[Fractionalloc]init];43.Fraction*frac3=[[Fractionalloc]initWithNumerator:344.denominator:10];45.46.//setthevalues47.48.[fracsetNumerator:1];49.50.[fracsetDenominator:3];51.52.//combinedset53.54.[frac2setNumerator:1andDenominator:5];55.56.//printit57.58.printf("Thefractionis:");59.[fracprint];
6〇,61.printf(M\nn);62.63.printf("Fraction2is:n);64.65.[frac2print];66.67.printf(n\nn);68.69.printf("Fraction3is:”);70.71.[frac3print];72.73.printf("\n");74.75.//freememory76.77.[fracrelease];78.79.[frac2release];80.81.[frac3release];82.83.return0;84.85.}outputThefractionis:1/3.Fraction2is:1/5.Fraction3is:3/10©interface裡的宣告就如同正常的函式。©implementation使用了一个新的关键字:super如同Java,Objective-C只有一个parentclass(父类别)。使用[superinit]来存取Superconstructor»这个动作需要适当的继承设计。你将这个动作回传的instance指派给另一新个关键字:self。Self很像C++与Java的this指标。if(self)跟(self!=nil)ー样,是为了确定superconstructor成功传回了一个新物件。nil是Objective-C用来表达C/C++中NULL的方式,可以引入NSObject来取得。当你初始化变数以后,你用传回self的方式来传回自己的位址。预设的建构子是-(id)inito技术上来说,Objective-C中的建构子就是ー个"init"method,而不像C++与Java有特殊的结构。存取权限预设的权限是0protectedJava实作的方式是在methods与变数前面加上public/private/protected修饰语,而Objective-C的作法则更像C++对于instancevariable(译注:C++术语一般称为datamembers)的方式。!,Access,h#import.@interfaceAccess:NSObject{.@public
9.intpublicVar;10.11.12.@privateVar;15.16.intprivateVar2;17.18.@protectedVar;21.22.}23.24.@end25.26.Access.m27.28.#import"Access.hn29.30.@implementationAccess31.32.@end33.34.main.m35.36.#import"Access.hn37.38.♦main(intargc,constchar*argv[]){41.42.Access*a=[[Accessalloc]init];43.44.//works45.46.a->publicVar=5;47.48.printf("publicvar:%i\n"za->publicVar);49.50.//doesn1tcompile51.//a->privateVar=10;. //printf("privatevar:%i\nnra->privateVar);[arelease];. return0;)outputpublicvar:5如同你所看到的,就像C++中private:[listofvars]public:[listofvars]的格式,它只是改成了@private,©protected,等等。ClasslevelaccessClassA.h.,#import.staticintcount;.@interfaceClassA:NSObject..+(int)initCount;+(void)initialize;@end.ClassA.m. #import"ClassA.hH@implementation ClassA-(id)init{. self=[superinit];
2425242526272829303132333435363738394041424344454647484950515253545556575859returnself;}+(int)initCount{returncount;}+(void)initialize{count=0;)@endmain.m#import"ClassA.hH#importintmain(intargc,constchar*argv[]){ClassA*cl=[[ClassAalloc]init];ClassA*c2=[[ClassAalloc]init];//printcount606162636465ClassA*c3[[ClassAalloc]init];//printcountagainprintf("ClassAcount:%i\n”,606162636465ClassA*c3[[ClassAalloc]init];//printcountagainprintf("ClassAcount:%i\n”,[ClassAinitCount]);[clrelease];[c2release];[c3release];return0;.}output.ClassAcount:2..ClassAcount:3staticintcount=0;这是classvariable宣告的方式。其实这种变数摆在这裡并不理想,比较好的解法是像Java实作staticclassvariables的方法。然而,它确实能用。+(int)initCount:这是回传count值的实际methodo请注意这细微的差别!这裡在type前面不用减号一而改用加号+。加号+表示这是ー个classlevelfunction。(译注:许多文件中,classlevelfunctions被称为classfunctions或classmethod)存取这个变数跟存取一般成员变数没有两样,就像ClassA中的count++用法。+(void)initializemethodis在Objective-C开始执行你的程式时被惣叫,而且它也被每个class惣叫。这是初始化像我们的count这类classlevelvariables的好地方
..9.1011121314151617181920212223242526272829303132333435363738异常情况(Exceptions)注意:异常处理只有MacOSX10.3以上オ支援。CupWarningException.h#import@interfaceCupWarningException:NSException@endCupWarningException.m. #importHCupWarningException.hH. @implementationCupWarningException. @end. CupOverflowException.h. #import. @interfaceCupOverflowException:NSException. @end. CupOverflowException.m. #importMCupOverflowException.hM. @implementationCupOverflowException. @endCup・h#import@interfaceCup:NSObject{
39.40.intlevel;41.42.)43.44.-(int)level;8.-(void)setLevel:(int)1;-(void)fill;49.50.-(void)empty;51.52.-(void)print;53.54.@end55.56.Cup.m0.#importnCup.hM♦importnCupOverflowException.hH61.62.♦import"CupWarningException.h"63.64.♦import8.69.70.♦import@implementationCup-(id)init{71.72.self=[superinit];73.74.if(self){75.76.[selfsetLevel:0];77.78.}2.returnself;}83.84.-(int)level{85.86.returnlevel;87.88.}89.90.-(void)setLevel:(int)1{91.92.llevel=1;93.94.if(level>100){95.96.//throwoverflow97.98.NSException*e=[CupOverflowException99.100.exceptionWithName:@HCupOverflowExceptionn101.102.reason:@"Thelevelisabove100n103.104.userlnfo:nil];105.106.@throwe;107.108.}elseif(level>=50){109.110.//throwwarning111.112.NSException*e=[CupWarningException113.114.exceptionWithName:@MCupWarningExceptionn115.116.reason:@"Thelevelisaboveorat50"117.118.userinfo:nil];119.120.@throwe;121.122.}elseif(level<0){123.124.//throwexception125.126.NSException*e=[NSException127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170exceptionWithName:@MCupUnderflowException11reason:@"Thelevelisbelow〇”userinfo:nil];@throwe;})(void)fill{[selfsetLevel:level+10];}(void)empty{[selfsetLevel:level-10];}(void)print{printf("Cuplevelis:%i\n",level);}@endmain.m#import"Cup.h"import"CupOverflowException.h"import"CupWarningException.h"import♦import
171.#import172.173.#main(intargc,constchar*argv[]){176.177.NSAutoreleasePool*pool=[[NSAutoreleasePool]init];178.179.Cup*cup=[[Cupalloc]init];180.181.inti;182.183.//thiswillwork184.185.for(i=0;i<4;i++){186.187.[cupfill];188.189.[cupprint];190.191.}192.193.//thiswillthrowexceptions194.195.for(i=0;i<7;i++){196.197.@try(198.199.[cupfill];200.201.}@catch(CupWarningException*e){202.203.printf("%s:",[[ename]cString]);204.205.}@catch(CupOverflowException*e){206.207.printf("%s:",[[ename]cString]);208.209.}@finally{210.211.[cupprint];212.213.}alloc17.217.//throwagenericexception19.220.@try{[cupsetLevel:-1];}@catch(NSException*e){[ereason]printf("%s:%s\n”,[[ename]cString],[[ereason]cString]);}//freememory[cuprelease];[poolrelease];.}output1.Cuplevelis:102.3.Cuplevelis:204.5.Cuplevelis:306.7.Cuplevelis:408.9.CupWarningException:Cuplevelis:5010.11121314151617CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:60708090CupWarningExceptionCupWarningException:Cuplevelis:100CupOverflowException:Cuplevelis:110. CupUnderflowException:Thelevelisbelow0NSAutoreleasePool是ー个记忆体管理类别。现在先别管它是干嘛的。Exceptions(异常情况)的丢出不需要扩充(extend)NSException物件,你可简单的用id来代表它:©catch(ide){...}还有一个finally区块,它的行为就像Java的异常处理方式,finally区块的内容保证会被惣叫。Cup.m裡的0/?CupOverflowException・是ー个NSString常数物件。在Objective-C中,©符号通常用来代表这是语言的衍生部分。C语言形式的字串(Cstring)就像C/C++ー样是"Stringconstant"的形式,型别为char*oObjective-C代码学习大纲(4)2011-05-1114:06佚名otiemey我要评论(4)字号:TlT
收藏エ3 4- Iロ F本文为台湾出版的《Objective-C学习大纲》的翻译文档,系统介绍了 :Objective-C代码,很多名词为台湾同胞特指词汇,在学习时仔细研读才能j体会。 :AD:2013大数据全球技术峰会低价抢票中セ继承、多型(Inheritance,Polymorphism)以及其他物件导向功能id型别Objective-C有种叫做id的型别,它的运作有时候像是void*,不过它却严格规定只能用在物件。Objective-C与Java跟C++不ー样,你在嗯叫ー个物件的method时,并不需要知道这个物件的型别。当然这个method一定要存在,这称为Objective-C的讯息传递。!,Fraction・h..#import.@interfaceFraction:NSObject{intnumerator;intdenominator;}-(Fraction*)initWithNumerator:(int)ndenominator:(int)d;.. -(void)print;. -(void)setNumerator:(int)d;-(void)setDenominator:(int)d;-(void)setNumerator:(int)nandDenominator:(int)d;. -(int)numerator;.-(int)denominator;@end
29.Fraction.m.♦importHFraction.hn♦import@implementationFraction-(Fraction*)initWithNumerator:(int)ndenominator(int)d(self=[superinit];if(self){[selfsetNumerator:nandDenominator:d];.)returnself;}-(void)print{printf(n%i/%inznumerator,denominator);...}(void)setNumerator:(int)nnnumerator=n;}(void)setDenominator:(int)ddenominator=d;}(void)setNumerator:(int)n{d(andDenominator:(int)d{71.72.nnumerator=n;73.74.ddenominator=d;75.76.}77.78.-(int)denominator{79.80.returndenominator;81.82.)83.84.-(int)numerator{85.86.returnnumerator;87.88.}89.90.@end91.92.Complex.h93.94.#import95.96.@interfaceComplex:NSObject{97.98.doublereal;99.100.doubleimaginary;101.102.}103.-(Complex*)initWithReal:(double)randlmaginary:(double)i;104.105.106.-(void)setReal:(double)r;107.108.-(void)setImaginary:(double)i;109.i;110.-(void)setReal:(double)randlmaginary:(double)111.112.-(double)real;113.114.-(double)imaginary;115.116.-(void)print;117.118.@end22.Complex,m#import"Complex.h"123.124.#import125.126.@implementationComplex127.-(Complex*)initWithReal:(double)randlmaginary:(double)i{34.135.136.self=[superinit];if(self){[selfsetReal:randlmaginary:i];)40.141.142.returnself;}-(void)setReal:(double)r{143.144.rreal=r;145.146.}147.148.-(void)setImaginary:(double)i{149.150.iimaginary=i;151.152.153.i(}-(void)setReal:(double)randlmaginary:(double)
155.156.rreal=r;157.158.iimaginary=i;159.160.}161.162.-(double)real{163.164.returnreal;165.166.)167.168.-(double)imaginary{169.170.returnimaginary;171.172.}173.174.-(void)print{175.176.printf("%_f+%_fiM,real,imaginary);177.178.)179.180.@end181.182.main.m183.184.#import185.186.#import"Fraction.hn187.188.#import"Cmain(intargc,constchar*argv[]){191.192.//createanewinstance193.Fraction*frac=[[Fractionalloc]initWithNumerator:1194.denominator:10];195.Complex*comp=[[Complexalloc]initWithReal:10andlmaginary:15];
197.198.idnumber;199.200.//printfraction201.202.number=frac;203.204.printf("Thefractionis:");205.206.[numberprint];207.208.printf("\n");209.210.//printcomplex211.212.number=comp;213.214.printf("Thecomplexnumberis:");215.216.[numberprint];217.218.printf("\n");219.220.//freememory221.222.[fracrelease];223.224.[comprelease];225.226.return0;227.}outputThefractionis:1/10Thecomplexnumberis:10.000000+15.OOOOOOi这种动态连结有显而易见的好处。你不需要知道你嗯叫method的那个东西是什么型别,如果这个物件对这个讯息有反应,那就会唤起这个methodo..9.1011121314151617181920212223242526272829303132333435这也不会牵涉到ー堆繁琐的转型动作,比如在Java裡嗯叫一个整数物件的,intValue()就得先转型,然后才能惣叫这个methodo继承(Inheritance)Rectangle.h#import@interfaceRectangle:NSObject{intwidth;intheight;}(Rectangle*)initWithWidth:(int)wheight:(int)h;(void)setwidth:(int)w;(void)setHeight:(int)h;(void)setwidth:(int)wheight:(int)h;(int)width;(int)height;(void)print;@endRectangle.m#import"Rectangle・h”#import@implementationRectangle
36.37.-(Rectangle*)initWithWidth:(int)wheight:h{38.39.self=[superinit];40.41.if(self){42.43.[selfsetwidth:wheight:h];44.45.)46.47.returnself;48.49.}50.51.-(void)setwidth:(int)w{52.53.wwidth=w;54.55.}56.57.-(void)setHeight:(int)h{58.59.hheight=h;60.61.)62.63.-(void)setwidth:(int)wheight:(int)h{64.65.wwidth=w;66.67.hheight=h;68.69.}70.71.-(int)width{72.73.returnwidth;74.75.)76.77.-(int)height{78.(int)
79.80.returnheight;81.82.)83.84.-(void)print{85.printf("width=%i,height=%i”,width,height);86.87.88.)89.90.@end91.92.Square.h93.94.#import"Rectangle.h"95.96.@interfaceSquare:Rectangle97.98.-(Square*)initWithSize:(int)s;99.100.-(void)setSize:(int)s;101.102.-(int)size;103.104.@end105.106.Square.m107.108.#import"Square.h"109.110.@implementationSquare111.112.-(Square*)initWithSize:(int)s{113.114.self=[superinit];115.116.if(self){117.118.[selfsetSize:s];119.120.}121.returnself;122.123. )124.125.126.-(void)setsize:(int)s{127.128.width=s;129.130.height=s;131.132.}133.134.-(int)size{135.136.returnwidth;137.138.)139.140.-(void)setwidth:(int)w{141.142.[selfsetsize:w];143.144.}145.146.-(void)setHeight:(int)h{147.148.[selfsetsize:h];149.150.}151.152.@end153.154.main.m155.156.#importHSquare.hM157.158.♦import"Rectangle.h"159.160.♦main(intargc,constchar*argv[]){163.Rectangle*rec=[[Rectanglealloc]initWithWidth:10height:20];165.Square*sq=[[Squarealloc]initWithSize:166.167.//printem168.169.printf("Rectangle:");170.171.[recprint];172.173.printf("\n");174.175.printf("Square:");176.177.[sqprint];178.179.printf("\n");180.181.//updatesquare182.183.[sqsetwidth:20];184.185.printf("Squareafterchange:");186.187.[sqprint];188.189.printf("\n");190.191.//freememory192.193.[recrelease];194.195.[sqrelease];196.197.return0;198.199.}output15];Rectangle:width=10,height=20.Square:width=15,height=15Squareafterchange:width=20,height=20继承在Objective-C裡比较像Java。当你扩充你的superclass(所以只能有一个parent)»你想自订这个superclass的method»只要简单的在你的childclassimplementation裡放上新的实作内容即可。而不需要C++裡呆呆的virtualtable〇这裡还有一个值得玩味的地方,如果你企图像这样去惣叫rectangle的constructor:Square*sq=[[Squarealloc]initWithWidth:10height:15],会发生什么事?答案是会产生一个编译器错误。因为rectangleconstructor回传的型别是Rectangle*,而不是Square*,所以这行不通。在某种情况下如果你真想这样用,使用id型别会是很好的选择。如果你想使用parent的constructor,只要把Rectangle・回传型别改成id即可。动态识别(Dynamictypes)这裡有一些用于Objective-C动态识别的methods(说明部分採中英并列,因为我觉得英文比较传神,中文怎么译都怪):1.-(BOOL)isKindOfClass:classObjisobjectadescendentormemberofclassObj此物件是否是classObj的子孙或ー员1.-(BOOL)isMemberOfClass:classObjisobjectamemberofclassObj此物件是否是classObj的一员1.-(BOOL)respondsToSelector:selectordoestheobjecthaveamethodnamedspecifiecbytheselector此物件是否有叫做selector的method+(BOOL)instancesRespondToSelector:selectordoesanobjectcreatedbythisclasshavetheabilitytorespondtothespecifiedselector此物件是否是由有能力回应指定selector的物件所产生-(id)performSelector:selectorinvokethespecifiedselectorontheobject唤起此物件的指定selector所有继承自NSObject都有一个可回传ー个class物件的classmethodo这非常近似于Java的getClass()methodo这个class物件被使用于前述的methods中。Selectors在Objective-C用以表示讯息。下ー个範例会秀出建立selector的语法。!,main.m..#importnSquare.hH..#import"Rectangle・h”.#main(intargc,constchar*argv[]){Rectangle*rec=[[Rectanglealloc]initWithWidth:10height:20];Square*sq=[[Squarealloc]initWithSize:15];.//isMemberOfClass. //true
192021222324252627282930313233343536373839404142434445464748495051525354555657YES)if([sqisMemberOfClass:[Squareclass]]printf(nsquareisamemberofsquareclass\nM);YES)}//falseif([sqisMemberOfClass:[Rectangleclass]]==YESprintf(Msquareisamemberofrectangleclass\nM))//falseif([sqisMemberOfClass:[NSObjectclass]]==YESprintf(Msquareisamemberofobjectclass\nM);}//isKindOfClass//trueif([sqisKindOfClass:[Squareclass]]==YES){printf(Msquareisakindofsquareclass\nn);}//trueif([sqisKindOfClass:[Rectangleclass]]==YES)printf(Msquareisakindofrectangleclass'n");
//trueif([sqisKindOfClass:[NSObjectclass]]==YES)(printf(Msquareisakindofobjectclass\nn);}//respondsToSelector//trueif([sqrespondsToSelector:@selector(setsize:)]==YES){printf(nsquarerespondstosetsize:method'n");}//falseif([sqrespondsToSelector:@selector(nonExistant)]==YES){printf(nsquarerespondstononExistantmethod"")J)IItrueif([SquarerespondsToSelector:©selector(alloc)]==YES){printf("squareclassrespondstoallocmethod\n")t}5859606162636465666768697071727374757677787980818283848586878889909192939495//instancesRespondToSelector//false7.square.square.square.square.squareif([RectangleinstancesRespondToSelector:@selector(setsize:)]==YES){98.99. printf(Hrectangleinstancerespondstosetsize:method\n”);03. //true104.if([SquareinstancesRespondToSelector:@selector(setSize:)]==YES){.printf(nsquareinstancerespondstosetSize:method\nM);}//freememory[recrelease];.[sqrelease];return0;118.)outputisamemberofsquareclassisakindofsquareclassisakindofrectangleclassisakindofobjectclassrespondstosetSize:methodsquareclassrespondstoallocmethodsquareinstancerespondstosetsize:methodCategories当你想要为某个class新增methods»你通常会扩充(extend,即继承)它。然而这不一定是个完美解法,特别是你想要重写ー个class的某个功能,但你却没有姬始码时。Categories允许你在现有的class加入新功能,但不需要扩充它。Ruby语言也有类似的功能。FractionMath.h..#import"Fraction・h”..@interfaceFraction(Math).-(Fraction*)add:(Fraction*)f;.-(Fraction*)mul:(Fraction*)f;-(Fraction*)div:(Fraction*)f;-(Fraction*)sub:(Fraction*)f;.@endFractionMath.m. #import"FractionMath.h"@implementationFraction (Math)-(Fraction*)add:(Fraction*> f{.return[[Fractionalloc]initWithNumerator:numerator*[fdenominator]+. denominator*[fnumerator]9. denominator:denominator*[fdenominator]];30.
3132333435363738394041424344454647484950515253545556575859606162636465666768697071-(Fraction*)mul:(Fraction*)f{return[[Fractionalloc]initWithNumerator:numerator*[fnumerator]denominator:denominator*[fdenominator]];)(Fraction*)div:(Fraction*)f{return[[Fractionalloc]initWithNumerator:numerator*[fdenominator]denominator:denominator*[fnumerator]];)(Fraction*)sub:(Fraction*)f{return[[Fractionalloc]initWithNumerator:numerator*[fdenominator]-denominator*[fnumerator]denominator:denominator*[fdenominator]];}@endmain.m♦import♦import"Fraction.h"import"FractionMath•h”intmain(intargc,constchar*argv[]){//createanewinstance
Fraction*fracl=[[Fractionalloc]initWithNumerator:1denominator:3];. Fraction*frac2=[[Fractionalloc]initWithNumerator:2denominator:5];. Fraction*frac3=[fraclmul:frac2];//printit[fraclprint];. printf(Hn);.[frac2print];printf("=");89. [frac3print];printf(”ヽn");//freememory.[fraclrelease];[frac2release];[frac3release];return0;}output1.1/3*2/5=2/15重点是@implementation跟@interface这两行:©interfaceFraction(Math)以及@implementationFraction(Math).(同一个class)只能有一个同名的category»其他的categories得加上不同的、独ー无二的名字。Categories在建立privatemethods时十分有用。因为Objective-C并没有像Java这种private/protected/publicmethods的概念,所以必须要使用categories来达成这种功能。作法是把privatemethod从你的classheader(.h)档案移到implementation(.m)档案。以下是此种作法ー个简短的範例。MyClass.h.#import..@interfaceMyClass:NSObject.-(void)publicMethod;..@endMyClass.m#import"MyClass・h”.#import. @implementationMyClass-(void)publicMethod{printf("publicmethod\n");.).@end//privatemethods@interfaceMyClass(Private)-(void)privateMethod;@end.. @implementationMyClass (Private)-(void) privateMethod{printf( "privatemethod\n");}@end.main.m#import"MyClass.h"9. intmain(intargc,constchar*argv[]){MyClass*obj=[[MyClassalloc]init];//thiscompiles.. [objpublicMethod];. //thisthrowserrorswhencompiling. //[objprivateMethod];//freememory[objrelease];return0;)output..PosingPosing有点像categories,但是不太ー样。它允许你扩充一•个class,并且全面性地的扮演(pose)这个superclass。例如:你有一个扩充NSArray的NSArrayChiId物件。如果你让NSArrayChild扮演NSArray,则在你的程式码中所有的NSArray都会自动被替代为NSArrayChild。FractionB.h..#import“Fraction・h”..@interfaceFractionB:Fraction,-(void)print;.@endFractionB.m#import"FractionB.h".#import@implementationFractionB-(void)print{printf("(%i/%i)"znumeratorrdenominator);}@endmain.m#import#import"Fraction.h"
33343536373839404142434445464748495051525354555657585960616263646566676869#importMFractionB.hHintmain(intargc,constchar*argv[]){Fraction*frac=[[Fractionalloc]initWithNumerator:3denominator:10];//printitprintf("Thefractionis:”);[fracprint];printf("\n");//makeFractionBposeasFraction[FractionBposeAsClass:[Fractionclass]];Fraction*frac2=[[Fractionalloc]initWithNumerator:3denominator:10];//printitprintf("Thefractionis:");[frac2print];printf("\n");//freememory[fracrelease];[frac2release];return0;}outputfractionis:3/10
2.3.Thefractionis:(3/10)这个程式的输出中,第一个fraction会输出3/10,而第二个会输出(3/10)〇这是FractionB中实作的方式。poseAsClass这个method是NSObject的一部份,它允许subclass扮演superclassoProtocolsObjective-C裡的Protocol与Java的interface或是C++的purelyvirtualclass相同。Printing.h^protocolPrinting-(void)print;@endFraction.h#import#import"Printing"@interfaceFraction:NSObject{intnumerator;intdenominator;)-(Fraction*)initWithNumerator:(int)ndenominator:(int)d;-(void)setNumerator:(int)d;-(void)setDenominator:(int)d;-(void)setNumerator:(int)nandDenominator:(int)d;-(int)numerator;-(int)denominator;@endFraction.m#import"Fraction."#import@implementationFraction-(Fraction*)initWithNumerator:(int)ndenominator:(int)d{246.self=[superinit];if(self){[selfsetNumerator:nandDenominator:d];)returnself;}-(void)print{260.printf("%i/%i",numerator,denominator);}264.-(void)setNumerator:(int)n{nnumerator=n;)-(void)setDenominator:(int)d{ddenominator=d;}276.-(void)setNumerator:(int)nandDenominator:(int)d{nnumerator=n;ddenominator=d;)-(int)denominator{returndenominator;)290.-(int)numerator{returnnumerator;)-(Fraction*)copyWithZone:(NSZone*)zone{return[[FractionallocWithZone:zone]initWithNumerator:numeratordenominator:denominator];)@endComplex.h#import#importHPrinting.hn@interfaceComplex:NSObject{doublereal;doubleimaginary;)-(Complex*)initWithReal:(double)randlmaginary:(double)i;-(void)setReal:(double)r;"(void)setImaginary:(double)i;325."(void)setReal:(double)randlmaginary:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年跨国球员转会合同范本
- 2025商业租赁合同书大全
- 2025专卖店合同专卖店申请加盟合同
- 文言文古诗词文学文化常识知识点
- 2025《设备采购合同范本》
- 《复习大纲梳理》课件
- 课件:人格尊严权的法律保障-教学内容与讨论
- 《城市规划管理与控制策略研究》课件
- 三峡电力职业学院《资产评估案例分析》2023-2024学年第一学期期末试卷
- 南方科技大学《历史学前沿与评论》2023-2024学年第一学期期末试卷
- UML期末复习题库(便于打印版)
- 《城镇燃气经营企业服务质量评价》
- 手术室降低巡回护士外出
- 肺结核的护理个案
- 建设项目全过程工程咨询-第二次形成性考核-国开(SC)-参考资料
- 化工联锁培训
- 儿童户外活动教育
- 中小学教育惩戒规则培训
- 海南省三亚购房合同
- 产科学说:臀位分娩的医学探讨
- GB/T 44692.1-2024危险化学品企业设备完整性第1部分:管理体系要求
评论
0/150
提交评论