• Objective-C入门教程(摘录)


    •  1 #import<Foundation/Foundation.h> 
       2 
       3  @interfaceCattle:NSObject{ 
       4 
       5     intlegsCount; 
       6 
       7 } 
       8 
       9   -(void)saySomething; 
      10 
      11   -(void)setLegsCount:(int)count; 
      12 
      13 @end
    • 在Objective-C里面,类的定义从@interface开始到@end结束,也就是说,编译器看到了@interface就知道了这是类的定义的开始,看到了@end就知道,类的定义结束了。
    • 关于“:NSObject”我们现在可以理解为,通过这样写,我们免费获得了苹果公司为我们精心准备的一系列的类和对象的必备的方法。NSObject被称为rootclass,也就是根类。
    • 大家现在来看第5行。我们以前把这个东西叫做变量,我们从现在开始,需要精确的使用Objective-C的用语了,这是实体变量(instancevariables,在有的英文资料里面会简写为iVars)。
    • 第9行的第一个字母是一个减号“-”。这个减号就是告诉编译器,减号后面的方法,是实体方法(instancemethod)。实体方法的意思就是说,这个方法在类没有被实体化之前,是不能运行的。我们在这里看到的是减号,在有减号的同时也有加号,我们把带加号的方法称为类方法(classmethod),和实体方法相对应,类方法可以脱离实体而运行。

    好了,我们在这里总结一下,类的定义方法如下: 
    @interface类的名字:父类的名字{ 实体变量类型实体变量名字;  

    ...

    -(返回值类型)方法名字; 
    +(返回值类型)方法名字; 
    -(返回值类型)方法名字:(变量类型)变量名字标签1:(变量类型)变量1名字;

    ...

     @end

    • “Cattle.m”文件: 
       
      #import"Cattle.h"  
      @implementationCattle 
      -(void)saySomething 
      { 
      NSLog(@"Hello,Iamacattle,Ihave%dlegs.",legsCount);
       } 
      -(void)setLegsCount:(int)count 10
      { 
      legsCount=count; 
      } 
      @end 
    • 我们来看第4行和第13行,和头文件里面的@一样,我们这里类的定义也是使用的编译导向。编译器会把从@implementation到@end之间的部分看作是类的定义。@implementation的后面有一个空格,空格的后面是我们的类的名字Cattle,这是在告诉编译器,我们要定义Cattle类了。第4行和第13行之间是我们在头文件里面定义的实体方法或者类方法的定义部分,当然我们的类如果没有任何的实体方法和类方法的话,我们也许要写上@implementation和@end,把中间留为空就可以了。 

      第5行是我们定义的saySomething的实现,我们可以发现第5行的内容和头文件Cattle.h的第7行是一致的。笔者个人认为在编写实体方法和类方法的定义的时候,为了避免手工输入产生的误差,可以从头文件当中把声明的部分拷贝过来,然后删除掉分号,加上两个花括弧。我们知道地6行到第8行是方法的定义的部分,我们再来看看第7行。第7行和第二章的Hello,World输出有些相似,只不过多了一个%d,还有实体变量legsCount,这个写法和C语言里面的printf是类似的,输出的时候会使用legsCount来替代字符串里面的%d。 
      第9行的内容和Cattle.h的第8行一致的,这个不需要再解释了。我们来看看第11行,第11行是在说,把参数count的数值赋值给实体变量legsCount。我们可以通过使用setLegsCount方法来控制Cattle对象里面legsCount的数值。 
      这部分内容的关键点为@implementation和@end,理解了这个东西,其余的就不难理解了。我们来总结一下,类的定义部分的语法:

      @implementation类的名字 -(方法返回值)方法名字 { 
      方法定义  } 
      -(方法返回值)方法名字:(变量类型)变量名字 { 
      方法定义  }  @end

       

    •  1 #import<Foundation/Foundation.h> 
       2 
       3 #import"Cattle.h" 
       4 
       5 intmain(intargc,constchar*argv[])
       6 {
       7  
       8 NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init]; 
       9 
      10 idcattle=[Cattlenew]; 
      11 
      12 [cattlesetLegsCount:4]; 
      13 
      14 [cattlesaySomething]; 
      15 
      16 [pooldrain]; 
      17 
      18 return0; 
      19 
      20 }

      同学们请看第10行的第一个单词id。id是英文identifier的缩写,我们在很多地方都遇到过id,比如说在博客园里面,我们都使用id来登陆系统的,我们的id就代表着系统的一个用户。由于id在一个系统当中是唯一的,所以系统获得我们的id之后就知道我们是谁了。Objective-C也是一样的道理,使用id来代表一个对象,在Objective-C当中,所有的对象都可以使用id来进行区分。我们知道一个类仅仅是一些数据外加上操作这些数据的代码,所以id实际上是指向数据结构的一个指针而已,相当于void*。 
      第10行的第二个单词是cattle,就是我们给这个id起的一个名字。当然,你可以起系统保留的名字以外的任何名字,不过为了维持代码的可读性,我们需要一个有意义的名字,我们这里使用头文字为小写的cattle。 
      第10行的[Cattlenew]是创建对象,new实际上是alloc和init的组合,在Objective-C里面创建对象是一个为对象分配内存和初始化的过程。new,alloc还有init定义在Cattle的超类NSObject里面,笔者将要在第7章里面详细的解释一下如何创建对象。在第7章之前我们都是用new来创建对象。

    • Objective-C里面的方法的使用和其他语言有些不同,Objective-C使用消息(Message)来调用方法。所以笔者认为在讲解第7行等号右边的部分之前,需要首先向大家介绍一个我们的新朋友,消息(Message)。所谓的消息就是一个类或者对象可以执行的动作。消息的格式如下: 
      [对象或者类名字方法名字:参数序列]; 首先我们观察到有两个中括弧,最右边的括弧之后是一个分号,当编译器遇到了这个格式之后会把中间的部分当作一个消息来发送。在上文的表达式当中,包括中括弧的所有部分的内容被称作消息表达式(Messageexpression),“对象或者类名字”被称作接收器(Receiver),也就是消息的接受者,“方法名字:参数序列”被称为一个消息(Message),“方法名字”被称作选择器(Selector)或者关键字(Keyword)。Objective-C和C语言是完全兼容的,C语言里面的中括弧用于表示数组,但是数组的格式明显和消息的发送的格式是不一样的,所以我们可以放心,编译器不会把我们的消息发送当作一个数组。 
      我们来回忆一下C语言里面函数的调用过程,实际上编译器在编译的时候就已经把函数相对于整个执行包的入口地址给确定好了,函数的执行实际上就是直接从这个地址开始执行的。Objective-C使用的是一种间接的方式,Objective-C向对象或者类(具体上是对象还是类的名字取决于方法是实体方法还是类方法)发送消息,消息的格式应该和方法相同。具体来说,第7行等号右边的部分[Cattlenew]就是说,向Cattle类发送一个new的消息。这样当Cattle类接收到new的时候,就会查找它可以相应的消息的列表,找到了new之后就会调用new的这个类方法,分配内存和初始化完成之后返回一个id,这样我们就得到一个对象。

           子类Subclass和超类Superclass

    • @interfaceCattle:NSObject{

      这段代码是在告诉编译器,我们的Cattle是继承的NSObject。在这段代码当中,NSObject是超类,Cattle是子类。通过这样写,我们曾经免费的得到了NSObject里面的一个方法叫做new:()

    • idcattle=[Cattlenew];
    • 在面向对象的程序设计当中,如果在子类当中继承了超类的话,那么超类当中已经生效的部分代码在子类当中仍然是有效的,这样就大大的提高了代码的效率。基于超类我们可以把我们需要追加的一些功能放到子类里面去,在本章里面,我们决定基于Cattle类,重新生成一个子类Bull:
       1 #import<Foundation/Foundation.h> 
       2 #import"Cattle.h"  
       3 @interfaceBull:Cattle
       4  5 NSString*skinColor; 
       6  7 -(void)saySomething; 
       8 -(NSString*)getSkinColor; 
       9 -(void)setSkinColor:(NSString*)color; 
      10 @end

      上段代码里面的第2行,是通知编译器,我们这个类的声明部分需要Cattle.h文件。这个文件我们已经很熟悉了,是我们在第3章曾经构筑过的,在本章里面,我们不会改变里面的任何内容。 
      第4行,就是在通知编译器,我们需要声明一个类名字叫做Bull,从Cattle里面继承过来。 第5行,我们追加了一个实例变量skinColor,用来保存Bull的颜色。 
      第7行,我们重载了在Cattle类里面已经有的(void)saySomething实例方法。重载(void)saySomething方法的主要原因是,我们认为Bull说的话应该和Cattle有所区别。 第8行到第9行,我们为Bull类声明了两个新的方法(NSString*)getSkinColor和
      (void)setSkinColor:(NSString*)color,分别用来设定和读取我们的实例变量skinColor。 好的,我们总结一下继承的时候的子类的格式。 

      @interface类的名字:父类的名字
      { 
      实体变量类型实体变量名字;
      } 
      -(返回值类型)重载的方法名字; 
      +(返回值类型)重载的方法名字; 
      -(返回值类型)其他的方法名字:(变量类型)变量名字:(变量类型)变量名字;  
      @end
  • 相关阅读:
    判断是否声明了某个特性
    如何月份英文缩写字符串转日期
    要捕捉System.Exception异常吗
    jenkins发布到nuget
    C# – Record, Class, Struct
    Google Maps Embed API & JavaScript API
    图片综合知识
    ASP.NET Core – ADO.NET
    CSS – 管理
    JavaScript Library – PhotoSwipe
  • 原文地址:https://www.cnblogs.com/ljwiOS/p/4816770.html
Copyright © 2020-2023  润新知