关闭

关闭

封号提示

内容

首页 object-c基础教程.pdf

object-c基础教程.pdf

object-c基础教程.pdf

上传者: 189*****628@sina.cn 2013-04-19 评分 4.5 0 98 13 445 暂无简介 简介 举报

简介:本文档为《object-c基础教程pdf》,可适用于IT/计算机领域,主题内容包含Translations:English|Chinese大纲开始吧o下载这篇教学o设定环境o前言o编译helloworld创建Classesoint符等。

Translations:English|Chinese大纲开始吧o下载这篇教学o设定环境o前言o编译helloworld创建Classesointerfaceoimplementationo把它们凑在一起详细说明o多重参数o建构子(Constructors)o访问权限oClasslevelaccesso异常情况(Exceptions)处理继承、多型(Inheritance,Polymorphism)以及其他面向对象功能oid型别o继承(Inheritance)o动态识别(Dynamictypes)oCategoriesoPosingoProtocols内存管理oRetainandRelease(保留与释放)oDeallocoAutoreleasePoolFoundationFrameworkClassesoNSArrayoNSDictionary优点与缺点更多信息开始吧o下载这篇教学所有这篇初学者指南的原始码都可以由objctargz下载。这篇教学中的许多范例都是由SteveKochan在ProgramminginObjectiveC一书中撰写。如果你想得到更多详细信息及范例请直接参考该书。这个网站上登载的所有范例皆经过他的允许所以请勿复制转载。o设定环境LinuxFreeBSD:安装GNUStep为了编译GNUstep应用程序必须先执行位于usrGNUstepSystemMakefilesGNUstepsh的GNUstepsh这个档案。这个路径取决于你的系统环境有些是在usr,someusrlib有些是usrlocal。如果你的shell是以cshtcsh为基础的shell则应该改用GNUStepcsh。建议把这个指令放在bashrc或cshrc中。MacOSX:安装XCodeWindowsNTX:安装cygwin或mingw然后安装GNUStepo前言这篇教学假设你已经有一些基本的C语言知识包括C数据型别、什么是函式、什么是回传值、关于指针的知识以及基本的C语言内存管理。如果您没有这些背景知识我非常建议你读一读KR的书:TheCProgrammingLanguage(译注:台湾出版书名为C程序语言第二版)这是C语言的设计者所写的书。ObjectiveC是C的衍生语言继承了所有C语言的特性。是有一些例外但是它们不是继承于C的语言特性本身。nil:在CC你或许曾使用过而在ObjectiveC中则是nil。不同之处是你可以传递讯息给nil(例如nilmessage)这是完全合法的然而你却不能对如法炮制。BOOL:C没有正式的布尔型别而在ObjectiveC中也不是「真的」有。它是包含在Foundationclasses(基本类别库)中(即importNSObjecthnil也是包括在这个头文件内)。BOOL在ObjectiveC中有两种型态:YES或NO而不是TRUE或FALSE。#importvs#include:就如同你在helloworld范例中看到的我们使用了#import。#import由gcc编译程序支援。我并不建议使用#include#import基本上跟h档头尾的#ifndef#define#endif相同。许多程序员们都同意使用这些东西这是十分愚蠢的。无论如何使用#import就对了。这样不但可以避免麻烦而且万一有一天gcc把它拿掉了将会有足够的ObjectiveC程序员可以坚持保留它或是将它放回来。偷偷告诉你Apple在它们官方的程序代码中也使用了#import。所以万一有一天这种事真的发生不难预料Apple将会提供一个支持#import的gcc分支版本。在ObjectiveC中method及message这两个字是可以互换的。不过messages拥有特别的特性一个message可以动态的转送给另一个对象。在ObjectiveC中呼叫对象上的一个讯息并不一定表示对象真的会实作这个讯息而是对象知道如何以某种方式去实作它或是转送给知道如何实作的对象。o编译helloworldhellom#import<stdioh>intmain(intargc,constchar*argv){printf("helloworldn")return}输出helloworld在ObjectiveC中使用#import代替#includeObjectiveC的预设扩展名是m创建classesointerface基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。Fractionh#import<FoundationNSObjecth>interfaceFraction:NSObject{intnumeratorintdenominator}(void)print(void)setNumerator:(int)n(void)setDenominator:(int)d(int)numerator(int)denominatorendNSObject:NeXTStepObject的缩写。因为它已经改名为OpenStep所以这在今天已经不是那么有意义了。继承(inheritance)以Class:Parent表示就像上面的Fraction:NSObject。夹在interfaceClass:Parent{}中的称为instancevariables。没有设定访问权限(protected,public,private)时预设的访问权限为protected。设定权限的方式将在稍后说明。Instancemethods跟在成员变数(即instancevariables)后。格式为:scope(returnType)methodName:(parameterType)parameterNamescope有class或instance两种。instancemethods以开头classlevelmethods以开头。Interface以一个end作为结束。oimplementation基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。Fractionm#import"Fractionh"#import<stdioh>implementationFraction(void)print{printf("ii",numerator,denominator)}(void)setNumerator:(int)n{numerator=n}(void)setDenominator:(int)d{denominator=d}(int)denominator{returndenominator}(int)numerator{returnnumerator}endImplementation以implementationClassName开始以end结束。Implement定义好的methods的方式跟在interface中宣告时很近似。o把它们凑在一起基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。mainm#import<stdioh>#import"Fractionh"intmain(intargc,constchar*argv){createanewinstanceFraction*frac=FractionallocinitsetthevaluesfracsetNumerator:fracsetDenominator:printitprintf("Thefractionis:")fracprintprintf("n")freememoryfracreleasereturn}outputThefractionis:Fraction*frac=Fractionallocinit这行程序代码中有很多重要的东西。在ObjectiveC中呼叫methods的方法是objectmethod就像C的object>method()。ObjectiveC没有value型别。所以没有像C的Fractionfracfracprint()这类的东西。在ObjectiveC中完全使用指针来处理对象。这行程序代码实际上做了两件事:Fractionalloc呼叫了Fractionclass的allocmethod。这就像malloc内存这个动作也做了一样的事情。objectinit是一个建构子(constructor)呼叫负责初始化对象中的所有变量。它呼叫了Fractionalloc传回的instance上的initmethod。这个动作非常普遍所以通常以一行程序完成:Object*var=ObjectallocinitfracsetNumerator:非常简单。它呼叫了frac上的setNumeratormethod并传入为参数。如同每个C的变体ObjectiveC也有一个用以释放内存的方式:release。它继承自NSObject这个method在之后会有详尽的解说。详细说明o多重参数目前为止我还没展示如何传递多个参数。这个语法乍看之下不是很直觉不过它却是来自一个十分受欢迎的Smalltalk版本。基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。Fractionh(void)setNumerator:(int)nandDenominator:(int)dFractionm(void)setNumerator:(int)nandDenominator:(int)d{numerator=ndenominator=d}mainm#import<stdioh>#import"Fractionh"intmain(intargc,constchar*argv){createanewinstanceFraction*frac=FractionallocinitFraction*frac=FractionallocinitsetthevaluesfracsetNumerator:fracsetDenominator:combinedsetfracsetNumerator:andDenominator:printitprintf("Thefractionis:")fracprintprintf("n")printitprintf("Fractionis:")fracprintprintf("n")freememoryfracreleasefracreleasereturn}outputThefractionis:Fractionis:这个method实际上叫做setNumerator:andDenominator:加入其他参数的方法就跟加入第二个时一样即method:label:label:label:而呼叫的方法是objmethod:paramlabel:paramlabel:paramlabel:paramLabels是非必要的所以可以有一个像这样的method:method:::简单的省略label名称但以:区隔参数。并不建议这样使用。o建构子(Constructors)基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。Fractionh(Fraction*)initWithNumerator:(int)ndenominator:(int)dFractionm(Fraction*)initWithNumerator:(int)ndenominator:(int)d{self=superinitif(self){selfsetNumerator:nandDenominator:d}returnself}mainm#import<stdioh>#import"Fractionh"intmain(intargc,constchar*argv){createanewinstanceFraction*frac=FractionallocinitFraction*frac=FractionallocinitFraction*frac=FractionallocinitWithNumerator:denominator:setthevaluesfracsetNumerator:fracsetDenominator:combinedsetfracsetNumerator:andDenominator:printitprintf("Thefractionis:")fracprintprintf("n")printf("Fractionis:")fracprintprintf("n")printf("Fractionis:")fracprintprintf("n")freememoryfracreleasefracreleasefracreleasereturn}outputThefractionis:Fractionis:Fractionis:interface里的宣告就如同正常的函式。implementation使用了一个新的关键词:super如同JavaObjectiveC只有一个parentclass(父类别)。使用superinit来存取Superconstructor这个动作需要适当的继承设计。你将这个动作回传的instance指派给另一新个关键词:self。Self很像C与Java的this指标。if(self)跟(self!=nil)一样是为了确定superconstructor成功传回了一个新对象。nil是ObjectiveC用来表达CC中的方式可以引入NSObject来取得。当你初始化变量以后你用传回self的方式来传回自己的地址。预设的建构子是(id)init。技术上来说ObjectiveC中的建构子就是一个"init"method而不像C与Java有特殊的结构。o访问权限预设的权限是protectedJava实作的方式是在methods与变量前面加上publicprivateprotected修饰语而ObjectiveC的作法则更像C对于instancevariable(译注:C术语一般称为datamembers)的方式。Accessh#import<FoundationNSObjecth>interfaceAccess:NSObject{publicintpublicVarprivateintprivateVarintprivateVarprotectedintprotectedVar}endAccessm#import"Accessh"implementationAccessendmainm#import"Accessh"#import<stdioh>intmain(intargc,constchar*argv){Access*a=Accessallocinitworksa>publicVar=printf("publicvar:in",a>publicVar)doesn'tcompilea>privateVar=printf("privatevar:in",a>privateVar)areleasereturn}outputpublicvar:如同你所看到的就像C中private:listofvarspublic:listofvars的格式它只是改成了private,protected,等等。oClasslevelaccess当你想计算一个对象被instance几次时通常有classlevelvariables以及classlevelfunctions是件方便的事。ClassAh#import<FoundationNSObjecth>staticintcountinterfaceClassA:NSObject(int)initCount(void)initializeendClassAm#import"ClassAh"implementationClassA(id)init{self=superinitcountreturnself}(int)initCount{returncount}(void)initialize{count=}endmainm#import"ClassAh"#import<stdioh>intmain(intargc,constchar*argv){ClassA*c=ClassAallocinitClassA*c=ClassAallocinitprintcountprintf("ClassAcount:in",ClassAinitCount)ClassA*c=ClassAallocinitprintcountagainprintf("ClassAcount:in",ClassAinitCount)creleasecreleasecreleasereturn}outputClassAcount:ClassAcount:staticintcount=这是classvariable宣告的方式。其实这种变量摆在这里并不理想比较好的解法是像Java实作staticclassvariables的方法。然而它确实能用。(int)initCount这是回传count值的实际method。请注意这细微的差别!这里在type前面不用减号而改用加号。加号表示这是一个classlevelfunction。(译注:许多文件中classlevelfunctions被称为classfunctions或classmethod)存取这个变数跟存取一般成员变数没有两样就像ClassA中的count用法。(void)initializemethodis在ObjectiveC开始执行你的程序时被呼叫而且它也被每个class呼叫。这是初始化像我们的count这类classlevelvariables的好地方。o异常情况(Exceptions)注意:异常处理只有MacOSX以上才支持。基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。CupWarningExceptionh#import<FoundationNSExceptionh>interfaceCupWarningException:NSExceptionendCupWarningExceptionm#import"CupWarningExceptionh"implementationCupWarningExceptionendCupOverflowExceptionh#import<FoundationNSExceptionh>interfaceCupOverflowException:NSExceptionendCupOverflowExceptionm#import"CupOverflowExceptionh"implementationCupOverflowExceptionendCuph#import<FoundationNSObjecth>interfaceCup:NSObject{intlevel}(int)level(void)setLevel:(int)l(void)fill(void)empty(void)printendCupm#import"Cuph"#import"CupOverflowExceptionh"#import"CupWarningExceptionh"#import<FoundationNSExceptionh>#import<FoundationNSStringh>implementationCup(id)init{self=superinitif(self){selfsetLevel:}returnself}(int)level{returnlevel}(void)setLevel:(int)l{level=lif(level>){throwoverflowNSException*e=CupOverflowExceptionexceptionWithName:"CupOverflowException"reason:"Thelevelisabove"userInfo:nilthrowe}elseif(level>=){throwwarningNSException*e=CupWarningExceptionexceptionWithName:"CupWarningException"reason:"Thelevelisaboveorat"userInfo:nilthrowe}elseif(level<){throwexceptionNSException*e=NSExceptionexceptionWithName:"CupUnderflowException"reason:"Thelevelisbelow"userInfo:nilthrowe}}(void)fill{selfsetLevel:level}(void)empty{selfsetLevel:level}(void)print{printf("Cuplevelis:in",level)}endmainm#import"Cuph"#import"CupOverflowExceptionh"#import"CupWarningExceptionh"#import<FoundationNSStringh>#import<FoundationNSExceptionh>#import<FoundationNSAutoreleasePoolh>#import<stdioh>intmain(intargc,constchar*argv){NSAutoreleasePool*pool=NSAutoreleasePoolallocinitCup*cup=Cupallocinitintithiswillworkfor(i=i<i){cupfillcupprint}thiswillthrowexceptionsfor(i=i<i){try{cupfill}catch(CupWarningException*e){printf("s:",enamecString)}catch(CupOverflowException*e){printf("s:",enamecString)}finally{cupprint}}throwagenericexceptiontry{cupsetLevel:}catch(NSException*e){printf("s:sn",enamecString,ereasoncString)}freememorycupreleasepoolrelease}outputCuplevelis:Cuplevelis:Cuplevelis:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupOverflowException:Cuplevelis:CupUnderflowException:ThelevelisbelowNSAutoreleasePool是一个内存管理类别。现在先别管它是干嘛的。Exceptions(异常情况)的丢出不需要扩充(extend)NSException对象你可简单的用id来代表它:catch(ide){}还有一个finally区块它的行为就像Java的异常处理方式finally区块的内容保证会被呼叫。Cupm里的"CupOverflowException"是一个NSString常数物件。在ObjectiveC中符号通常用来代表这是语言的衍生部分。C语言形式的字符串(Cstring)就像CC一样是"Stringconstant"的形式型别为char*。继承、多型(Inheritance,Polymorphism)以及其他面向对象功能oid型别ObjectiveC有种叫做id的型别它的运作有时候像是void*不过它却严格规定只能用在对象。ObjectiveC与Java跟C不一样你在呼叫一个对象的method时并不需要知道这个对象的型别。当然这个method一定要存在这称为ObjectiveC的讯息传递。基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。Fractionh#import<FoundationNSObjecth>interfaceFraction:NSObject{intnumeratorintdenominator}(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)denominatorendFractionm#import"Fractionh"#import<stdioh>implementationFraction(Fraction*)initWithNumerator:(int)ndenominator:(int)d{self=superinitif(self){selfsetNumerator:nandDenominator:d}returnself}(void)print{printf("ii",numerator,denominator)}(void)setNumerator:(int)n{numerator=n}(void)setDenominator:(int)d{denominator=d}(void)setNumerator:(int)nandDenominator:(int)d{numerator=ndenominator=d}(int)denominator{returndenominator}(int)numerator{returnnumerator}endComplexh#import<FoundationNSObjecth>interfaceComplex:NSObject{doublerealdoubleimaginary}(Complex*)initWithReal:(double)randImaginary:(double)i(void)setReal:(double)r(void)setImaginary:(double)i(void)setReal:(double)randImaginary:(double)i(double)real(double)imaginary(void)printendComplexm#import"Complexh"#import<stdioh>implementationComplex(Complex*)initWithReal:(double)randImaginary:(double)i{self=superinitif(self){selfsetReal:randImaginary:i}returnself}(void)setReal:(double)r{real=r}(void)setImaginary:(double)i{imaginary=i}(void)setReal:(double)randImaginary:(double)i{real=rimaginary=i}(double)real{returnreal}(double)imaginary{returnimaginary}(void)print{printf("ffi",real,imaginary)}endmainm#import<stdioh>#import"Fractionh"#import"Complexh"intmain(intargc,constchar*argv){createanewinstanceFraction*frac=FractionallocinitWithNumerator:denominator:Complex*comp=ComplexallocinitWithReal:andImaginary:idnumberprintfractionnumber=fracprintf("Thefractionis:")numberprintprintf("n")printcomplexnumber=compprintf("Thecomplexnumberis:")numberprintprintf("n")freememoryfracreleasecompreleasereturn}outputThefractionis:Thecomplexnumberis:i这种动态链接有显而易见的好处。你不需要知道你呼叫method的那个东西是什么型别如果这个对象对这个讯息有反应那就会唤起这个method。这也不会牵涉到一堆繁琐的转型动作比如在Java里呼叫一个整数对象的intValue()就得先转型然后才能呼叫这个method。o继承(Inheritance)基于"ProgramminginObjectiveC,"CopyrightbySamsPublishing一书中的范例并经过允许而刊载。Rectangleh#import<FoundationNSObjecth>interfaceRectangle:NSObject{intwidthintheight}(Rectangle*)initWithWidth:(int)wheight:(int)h(void)setWidth:(int)w(

精彩专题

职业精品

上传我的资料

热门资料

资料评价:

/ 51
所需积分:5 立即下载

意见
反馈

返回
顶部

Q