1.初次接触OC的时候,对接口的概念还是模模糊糊的,搞不明白什么是@property 和@interface
2.一般定义一个属性(也可理解为一个变量)都是用@property,最近碰到了在.h文件中@interface后面以扩展(在其后加上中括号)的形式定义属性,当时就懵逼了,如下图所示
3.预备知识,OC中一个类文件分为.h(head头文件)和.m(main主文件)。头文件就是传说中的接口文件,你可以在这里写出你允许别人使用你类中的哪些功能,这个接口就类似一个电视遥控器,上面的所有按钮就是一个个接口,你换台只需点一下‘下一个频道’就可以了,至于你按下这个按钮后,遥控和电视之间都做了什么操作你不需要care(这些操作就是写在.m文件里的)
一如既往,我们一起来举个浅显易懂的🌰
1.随便建立一个singleView的工程,在里面加两个类文件(继承UIViewController),分别叫Example和Example2
-如图所示
- 然后在Example类的.h文件里写上这些属性,在阅读OC的代码时我们会常看到别人在属性(变量)前面加个下划线?这是为什么呢,我们先不管,每种都写一个,这里我先在@Interface后面的中括号里定义了三个属性(均是字符串类型的 黄晓明、范冰冰、加了下划线的李治廷),然后在中括号之外用@property定义了两个属性(同样是字符串类型的angelababy和 加了个下划线的李易峰)
2.小实验
- 我们先打开Example.m看看这些属性在自己的类里有什么区别(左边是这个类的是.h文件右边是.m)
- 这里就随便给属性赋值了(就是等号右边的xxxxx),关键看访问的方式
- 卧槽!什么情况,李易峰前面多了一条那么长的下划线(我们在定义的时候明明只加了一个下划线),我们北鼻也是,自己多了一条下划线
- 但是我们用self.的方式可以正常访问这两个用@property定义的变量
这里用self访问属性和直接访问的区别就是:self方式其实是编译器会给这个属性一个赋值的方法[self setHuangxiaoming:huangxiaoming]来实现给huangxiaoming这个属性赋值
而另一种就是直接访问到huangxiaoming这个属性的地址,然后对它赋值
- 在@interface里定义的变量可以直接访问,形式没发生什么变化,但是用self.的方式访问不到这三个属性
我们看看这个self是什么
跳出的蓝色提示框说的很明白
- 在实例方法里的self 就是这个实例本身 (Example *const)
- 在类方法里的self就是这个类自己(const Class)
这两个self什么区别?我们试着去用两个self都去访问一下变量看看
- 哇塞!报错了,注意看带有➕号的那个方法里的self,也就是这个类是访问不到这些变量的无论用什么方式定义的
-
而上面的self却可以访问用@property标明的属性
我想大家已经早就想问了,那个initwith开头的一大串是什么东西
- 这里我们就能知道为什么定义变量的时候要在前面加一个下划线了
- 假如我们这里有个这样的函数来给这些属性赋值
- 看到了么,有小警告出来了,大概意思是这里的参数名和你的属性名撞衫了,傻傻分不清楚了
怎么解决? 我们可以这样
- 对于interface里的属性我们可以在定义的时候就在前面加个下划线,如图所示
- 对于@property定义的变量,xcode5以前我们需要在.m文件里加这句
@sythesize _angelaBaby = angelaBaby
- xcode以后编译器会自动帮我们加上这一句,不必手动去敲
-
这里我们大概明白了,加下划线就是为了避免与参数名同名的这样的尴尬,你也可以不加下划线,把参数用别的名字代替,但是那样你的函数读起来可就不那么顺了。
3.到目前为止,我们发现其实两种方式定义的属性并没什么大的区别,那么我们到隔壁老王家试试
- 我们先在Example2.m里import一下Example.h 这样你就能用Example这个类啦!
- 之后我们在viewdidload里先定义一个Example这个类的一个实例叫E1
- 然后用这个实例去访问她的成员,发现了什么?
- 这里我们就得到答案了!用@property标明的属性能被它的实例访问到,而直接在@interface里定义的属性,是访问不到的(只能在自己家里玩)
4.小总结一下
这两种定义属性的方式的却别是:
- @property 标明的属性 在本类中可以用self.的方式来访问 ;并会在.m里生成一个同名带下划线的属性 ;在别的类里也可以访问
- 在@interface后用扩展形式定义的属性 在本类中不能用self.的方式访问,在别的类里也无法访问