您当前的位置:首页 > 计算机 > 编程开发 > C语言

object-c中的点语法

时间:01-03来源:作者:点击数:

在前面的小程序中,我们会发现有这样的编码方式:
@property (nonatomic,copy)NSString * name;在这一节中,将会带领大家学习一下OC声明属性的几种方式以及怎么调用它们。

首先,我们要知道这段代码的作用是声明一个属性。在OC,先后有三种声明属性的方式:

方式1:直接在@interface中的大括号中声明
@interface Person : NSObject{
    NSString * name;
}
@end

方式2:在@interface中声明,然后在@property中声明,随后在.m文件中加入 @synthesize name=_name;。.h文件中:
@interface Person : NSObject{
    NSString * _name;//编写习惯,一般声明成员变量的时候名字前面加“_”
}
@property (nonatomic,copy)NSString * name;

@end
.m文件中:
@implementation Person

@synthesize name=_name;

@end

方式3:用@property中声明。
@interface Person : NSObject
@property (nonatomic,copy)NSString * name;

@end

这三种方式各有什么不同?

首先对比一下方式一和方式三:

方式一声明的name是成员变量,只能在类内部使用,不能在外部调用。

方式三声明的name可以从类外部被本类对象通过:对象.name的方式来调用。

在说一下方式二,这种写法是一种过时的声明变量的方式,Xcode在早期使用这种方式,它的效果和方式三是一样的,也有不同。虽然它相比于方式三看起来要麻烦,但是它的代码表达的很清楚。

首先声明一个成员变量_name,

@property (nonatomic,copy)NSString * name;这句的意思是为name声明并实现set和get方法(和点语法有关,后面会介绍)。

@synthesize name=_name;.m文件中的这一句将_name 赋值给了name属性,将两者进行了关联。

所以对于方式二这种编码方式,我们叫它:显式创建。

而对于方式三来说:@property (nonatomic,copy)NSString * name;

在这句代码的背后,做了这样几个工作:

首先隐式声明了一个成员变量_name,

然后内部声明并实现了name属性的set和get方法。

所以方式三被称作:隐式创建。

学到这,我们可能会有疑问,set和get方法是什么?它们和点语法有什么关系呢?下面我们一起来了解一下。

在OC编写代码中,我们采用点的方式来调用对象中的属性,或给属性赋值,或取出该属性的值。那么它到底是怎么实现的呢?这就跟OC的点语法相关。

由于OC本身是面向对象的,而面向对象的主要表现就是类这种数据类型,所以,学习OC,就少不了要和类打交道。

在使用类时,我们最多的就是使用类中的属性和方法,在对类中的属性进行操作之前,首先我们要获得它,那么就要用到我们的点语法。所以,在OC编程中,我认为点语法的学习是非常重要的,就像是人必须要吃饭一样。

在OC中,点语法的具体表现形式就是:对象.属性。我们知道了点语法的写法,可是它是怎么帮我们获取到属性的值的呢?我们学习一下。

其实,当我们通过写对象.属性来调取属性值的时候,OC帮我们调取了两个方法:set方法和get方法。

set方法是属性进行赋值时调用的方法,例如:
  people.name=@"ZhangSan";

在执行这段代码的时候,OC判断出来了这时赋值语句,所以它调用了属性的set方法,将ZhangSan这个字符串赋值给了people对象的name属性,也可以这么说,这句代码在执行的时候改变成了:
[people setName:@”ZhangSan”];

这是setName:的调用,方法中含有一个字符串型的形参。

set方法的具体实现:
-(void)setName:(NSString *)name{
      _name=name;
}

get方法获取属性时调用的方法,例如:
   NSString * theName=people.name;

这段代码实现的功能时将people对象的name属性赋值给theName字符串。

在执行这段代码的时候,OC判断出来了这是取值操作,所以它调用了属性的get方法,将people对象的name属性取了出来。同样,它在执行的时候改变成了:
NSString * theName=[people getName];

先把name属性值取出来,然后进行赋值。

get方法的具体实现:
-(NSString *)name{
    return _name;
}

那有朋友可能要问了,OC是怎么自己判断出来的呢,其实有这样一个规律可循:

在没有等号的情况下,默认是get方法。

在有等号的情况下,我们就要分两种情况:
  在等号左边是set方法。
  在等号右边是get方法。

学到这里,可能还有这样的疑问?我的类中没有显式set方法和get方法,它怎么会调用呢?

这就和我们前边提到的三种方式有关,方式一的这种写法没有自动产生该成员变量的set和get属性。

方式二在@property的时候,自动为该name属性添加了set 和get方法,只不过和其他代码集成在一起了。

对于编程来说,只有你想不到,没有你动手做不到的,如果你想要自己创建set和get方法,这也是可行的。

对于方式一来说,如果想通过使用set和get的形式对name进行访问,就需要自己创建set和get方法,而且必须是在.h中声明,在.m中实现,如果只在.m中实现而不在.h中声明也是不行,因为这种方式本身就没有set和get方法,本来就不能通过对象.属性的方式访问。

而对于方式三来说,就不需要这么麻烦。由于两种方式都已经隐式创建好了set和get方法。虽然我们无法让它们显示出来,但是我们可以重写set或get方法,也就是将隐藏的set或get方法覆盖。(在Xcode中编写的时候,对于重写的方法,我们只需要打“-setName”或“-name”,Xcode就给我们给我们提示,直接回车就可以了,非常方便)。

注意:方式三由于已经隐式创建好了set和get方法,所以如果我们同时重写了set和get方法,与@property声明的成员属性就不是一个成员属性了,是另外一个实例变量,而这个实例变量需要手动声明,就变成了方式二 。在实际开发过程中,要视情况而定。

对于方法二来说,由于声明了一个_name成员变量
@property (nonatomic,copy)NSString * name;相当于声明了name属性的set和get方法。
@synthesize name=_name;相当于在.m文件中对set和get方法进行实现

这一系列操作叫做:显式创建,在这种方式的前提下,我们可以同时对name属性进行set和get方法的重写而不会出错。

总结三种方式:

  • 如果只是声明一个变量,不需要从外部访问,就用方式一。
  • 如果需要外部访问,并且需要同时重写set和get方法,就用方式二。
  • 如果需要外部访问,可能会用到重写set或get方法,就用方式三。

通过这一节的学习,你应该能过解决下面的问题:

  • 1、在类中怎样声明属性以及怎么在类的外部调用类中的属性。
  • 2、类中属性在调用时的内部实现是怎样的?
  • 3、要学会使用属性的set和get方法并灵活运用。
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门