您的位置:首页 > 移动开发 > Objective-C

Objective-C语法区分

2015-11-06 18:17 369 查看
天苍苍,雪茫茫,风吹雾散见重楼

叶未落尽冬已到

对于从未接触过IOS开发,却熟悉另一语言开发的人来说,Objective-C可能是不易被接受的,因为其除了一些基本概念如对象,MVC,持久化,继承等等和其他语言有相似处外,不像Java,C#,安卓,VB等语法那样有共通性。

苹果开发除了使用苹果一体机和苹果笔记本外,大家还有以下选择:

苹果mini,搭配上支持苹果端口的显示器,OK的,一台苹果mini
3000多,而且也是苹果官方。
黑苹果,自从苹果采用Intel后,国内出现了一批黑苹果,它可以很好的运行MAC OS X系统,也不贵,不过苹果不提供升级,需要系统升级的时候,自己另找点花上不到100块升级下。
如果你的电脑CPU支持硬件虚拟化的话,那么可以安装MAC虚拟机,或者拷贝现成的虚拟机。虽然没有真机快,不过也够用啦(如果内存够,虚拟机也是蛮顺畅的)。
 如果你的私人电脑够牛,你又有足够的勇气和耐心,那么可以从网上找教程给自己的笔记本装MAC双系统。如:http://blog.sina.com.cn/s/blog_613830e70101ezj3.html。试验证明,这一点可行,不过稍有不慎,硬盘坏掉也有可能试验不成功。一个成功的教程这台笔记本上能成功,另一台一样的可能就出新问题。抱着可能成功的信念不断的试试试,也许你就能成功。不排除你是一次成功的案例。(我以前的例子是装坏了一台笔记本的硬盘,又换了个新的当时最适合装mac系统的笔记本,试验了3个月,终于在考试前夕OK了。不过现在的笔记本应该好多了。)

开发语言:IOS
应用开发使用的是Objective-C语言,以及去年公布的Swift语言。

对于熟悉其他语言的开发者来说,可能swift更好入门,不过由于90%的第三方工具是Objective-C,旧设备的不支持,现在市面上大部分还是在使用Objective-C,所以我们依然是使用Objective-C。但是大家不要担心以后会不会白学,因为Swift和Objective-C除了语法有很大差别外,并不会影响开发,使用二者的UI设计,框架,编程思想等等哪怕是依托的类库都是完全相同的。我们这门课,讲解语法的也只占用一节而已,后面的其实都是共用的,所以知道swift的人也不用担心。Swift是IOS8之后才支持的,Objective-C支持所有版本,并不是说苹果废弃了。

语法区别:

可能记的不全,如果以后遇到,可以提出,我再更新。以下Objective-C简称为OC。

OC是在C语言的基础上添加扩展而成,它可以调用C,但是OC本身实现与C又几乎完全不同,它自己定义了一些规则。

头文件和实现文件:

这点OC类似于C和C++,分为定义头文件(.h)和实现文件(.m),.h文件和C,C++一样,.m和他们的.c,.c++文件一样,C#和java没有这个概念,它只是把类的声明定义与实现分开在两个文件中,也就是一个类会有两个文件,一个.h一个.m,你可能会看到单独的.h定义文件,如定义一些枚举,常量类,协议等,但是不会有单独一个.m的情况。

引用:

有时我们会使用到类库中的方法或者调用其它类,大家都知道吧。这里只列出来,用法是一样的,只是规则这样写一样,你不要问我为什么是这样,这是OC的规则或规约,就好像如果我讲的是C#或java,应该没人问:为什么是using和import,而不是use和include呢?吧。如果好奇,那我只能说,这是规约,记住它,OK?

JAVA:

import java.io.IOException;
C#:

using System;
OC:

#import <Foundation/Foundation.h>
#import “TOSCommonDefinition.h”
#import会自动导入一次,不会重复导入,也就不会引起交叉编译。

#import<>引用系统文件,它用于对系统自带的头文件的引用,编译器会在系统文件目录下去查找该文件.也可认为是动态链接库的头文件引用。

#import””:用户自定义的文件用双引号引用,编译器首先会在用户目录下查找,然后到安装目录中查找。.a静态链接库里的头文件也是这样引用。

类声明和定义:

JAVA和C#:

public class 类名 extends 父类名 implements 接口名{
private 属性类型属性名;
public 返回类型方法名(参数类型参数名,…) {
方法实现体
}
}
大家所见的定义是这样的吧,在一个文件中,声明了类,在{}中定义它的属性和方法体实现。

OC中与其类似的是也有类声明和定义,继承和实现接口,只不过除了方法体实现是在.m文件中其他一般都在.h文件中,大家可能发现了我用的是“一般”,这个后面我会介绍,因为有一些私有属性和方法定义我们是放在.m中的,这个涉及到类的扩展,后面讲。

OC:(区别来喽)

.h
@interface 类名 : 父类名<协议1,协议2,…> //①
{ //②
@private 属性类型属性名1; //③
} //②
@property (变量属性) 属性类型属性名2; //④
+ (返回类型) 方法名1: (参数类型1)参数名1 参数标识: (参数类型2)参数名2 ; //⑤
– (返回类型) 方法名2: (参数类型1)参数名1 参数标识: (参数类型2)参数名2 ; //⑤
– (返回类型) 方法名3 //⑥
@end //⑦
.m
#import “该类头文件” //⑧
@implementation 类名//⑨
@synthesize 属性名2;//⑩
+ (返回类型) 方法名1: (参数类型1)参数名1 参数标识: (参数类型2)参数名2 //⑪
{
方法实现体
}
– (返回类型) 方法名2: (参数类型1)参数名1 参数标识: (参数类型2)参数名2
{
方法实现体
}
– (返回类型) 方法名3
{
方法实现体
}
@end //⑫
OK,一个简单的类结束了,有人可能会问,你这是定义的接口吧,怎么还实现了?NO,这是一个再正常不过的Objective-C类。以上加粗部分都是区别,下面一个个说:

1.    @interface:类的声明。这个关键字和Java/C#定义类时的class一个意思,是声明一个类,如果这里你有接口的悬念,先放肚子里。
类的定义放在@interface和@end之间。

2.    ①部分的【:】:代表这个后面跟着的是继承类,与Java/C#的extends同义。如果没有父类可以不写

3.    ①部分的【<>】:代表这个里面是该类所实现的协议,与Java/C#的implements同义。如果没有实现的协议,可以不写
一个类只能有一个父类,但是可以实现多个协议。

4.    ②部分的【{}】:属性在里面定义。

5.    ③部分的@private,和Java/C#的private一样,记得前面有【@】哦,代表访问权限,默认@private,另外还有@public,@protected,@package,简单说

@private:本类可以访问,子类不可以;

@protected:本类和子类都可以访问,其他类不可以;

@public:本类、子类、其他类都可以;

@package:对于framework内部,相当于@protected,对于framework外部,相当于@pravite.我没有用到过。

6.    ④部分的@property:属性声明,是不是疑问了“5里不就是属性定义吗?”。在OC里,即使你定义了@public访问权限,外部也是不能.出来的哦,需要设setter和getter方法,这点和Java/C#的get,set方法一样的。OC新加了@property和@synthesize,如此声明的属性是@public的,会自动生成setter、getter方法,而不用自己实现,是不是很方便。@property是声明,@synthesize在.m里是其实现。

7.    ⑤部分和⑥部分是方法定义,它与Java/C#不同:

*+和-:+代表这个方法是类方法(类名调用),-是实例方法(对象调用)。类方法有点类似Java/C#的static静态方法。是所有实例共享的

*访问权限:在.h定义的方法默认都是@public的

*返回值类型要用【()】括起来

*参数类型要用【()】括起来

*参数前面一定有【:】,【:】前可以有标识名也可以空,不过建议最好,且有实际意义,比如【initParam:(Integer)height
withWidth:(Integer) width】,”withWidth”对后面参数有一个说明。

*方法名:【方法名:
参数标识:】,没有参数的方法名才是【方法名】。比如【initParam:(Integer) height withWidth:(Integer) width】,方法名为“initParam:withWidth:”,如果@selector(initParam)可是找不到方法的哦。
定义的属性和方法都必须以【;】结尾

8.    ⑧部分:.m文件中一定会引用该类头文件的。必须的,否则,报错。

9.    @implementation:类的实现,后面跟类名。在.m文件,里面实现在.h或扩展类中定义的方法或@property。
类的实现放在@implementation和@end之间。

10. @synthesize:以【;】结尾,与头文件中@property一一对应。

11. ⑪部分就是方法实现体,本类的类方法、实例方法,协议的方法,扩展类的方法(私有方法)

12. @end:类定义体和实现体的结束标识,没有报错,就像上面Java/C#示例的【}】

协议:(接口)

上面我们一直提到协议这个词,大家先把UDP/TCP等等抛出去,你们脑海中的协议在IOS中通用。我这里说的协议是@protocol,也就是Java/C#的interface接口。它里面定义了一些方法列表,通过委托去调用,而<>了它的类都是它的委托类。和接口是一样的。

Java/C#:

public interface 接口名

{
方法列表

}

OC:

@protocol 协议名<父协议名>

-方法1

-方法2

@optional

-方法3

-方法4

@required

-方法4

@end

协议也可以继承父协议,这样实现该协议的类也需求实现其父类的方法。如果没有父协议,可以不写<>

从Objective-C2.0后,protocol添加了两个属性,@required和@optional,默认是@required,所以方法1、方法2和方法4都是@required。@optional是可选的,@required是实现类必须实现的,否则会报错。

方法调用:

先展示出来:

技术语言

方法调用(对象car调用run(time,distance))

C#

car.run(time,distance);

Java

car.run(time,distance);

Objective-C

[car run:time :distance];

方法调用时,OC使用的不是.而是[],一层代表一个函数,方法名上面说过了,是“run::”,OC中,虽然也说是方法调用,但是其实在Objective-C中,是没有方法调用这个概念的,在OC中叫做消息传递。在OC中方法和类是松耦合的,该类可以在运行时决定怎么处理这个消息。[car
run:time :distance]会被转换为objc_msgSend(car,run::,time,distance)是不是跟平时看到的方法一样了。每个类都有一个isa成员,它里面有一个方法列表,对应的是方法名和方法地址,以此来达到调用方法。

大家只需要知道OC是通过消息传递的方式调用方法的即可。会使用即可。

super,self:

技术语言

指向本类实例指针

指向父类实例指针

C#

this

base

Java

this

super

Objective-C

self

super

NSObject:

技术语言

基类

C#

Object

Java

Object

Objective-C

NSObject

id:

上面说到isa成员,其实id是指向isa的指针。其他语言中没有,是一个指向指针的指针,不需要这么深,你只要知道id是一个可以指向任一类型对象的指针,在概念上,类似Java
的Object类,可以转换为任何数据类型。

id name = [[NSString alloc] init];
这里id指向的是NSString类型对象。相当于了【NSString *】

切记:除了基本类型以外,如Integer,Float等,所有对象类型都是定义指针类型,必须加*,否则报错。如

NSString *name = [[NSString alloc] init];

nil:

类似null

分类Category:

不知道JAVA和C#有没有类似的概念,据我所知,Objective-C是我接触过的里面第一个。

使用Object-C中的分类,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以做到。具体概念就不说了,直接说实现和对我们的意义影响。

当我们需要扩展一个类的时候,按传统方式一般是写一个子类继承它,然后定义子类对象。如果又有一个新功能呢?继续继承,原来定义的实例除非改变为子类类型,否则不能访问新方法。这时候分类出现了。

定义:

譬如我们已经有一个Car类,方法有run。现在我们想添加一个stopping方法

@interfaceCar(motionCar)
{
-(void) stopping;
}
@implementation Car(motionCar)
{
-(void) stopping{
方法体
}
}
可以看出,其实和上面普通类定义区别不大,就是后面多了个【()】,括号中的是分类名,分类文件名一般是【原有类名+分类名称】

调用的时候如下:

Car *car = [[Car alloc] init];
[car run];
[car stopping];
分类中的方法就相当于往原类中添加方法。同样,注意点出现了,分类中的方法会影响到原类的所有子类,以及它们的实例对象。分类中的方法优先级高于原类,如果方法名与原类重名,那么就类似覆盖,会影响所有既存功能。所以除非必要,不要命名与原类同名方法。(多个分类出现同名方法,每个分类优先度是等同的,等概率事件)

另:分类只能添加新方法,无法添加新的属性。

扩展(Extension):

扩展和分类长得很像,但是()是空的,但是只是长的像哦,作用完全不同。

类的扩展可以添加新的属性和方法,放在原类的.m文件中。用于类的封装,定义类的私有属性和私有方法。方法实现依然在原类的@implementation中

.h
@interface Car:NSObject
{
-(void) run;
}
.m
@interface Car()
{
NSString *color;
-(void) stopping;
}
@implementation Car()
{
-(void) run{
方法体
}
-(void) stopping{
方法体
}
}
如上,run是public方法,stopping是私有方法,外界访问不到,color是新添加的属性,外界通过.h是看不到的,这样外部通过头文件看到的只是你想要让别人看到的方法和属性。是苹果所推荐的。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: