Objective-C:属性(@property)
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
苹果公司在Object-C 2.0 中引入了属性(property),它组合了新的预编译指令和新的属性访问语法。新的属性功能显著减少了必须编写的冗长代码的数量。
1 、@property关键字
可以使用@property关键字来声明类的属性(property),编译器能够自动生成属性名、setter方法、getter方法。其中@property是在@interface块中使用。
1.1 普通方式
如在myClass类中有_name属性,可以实现其setter和getter方法:
1 @interface myClass : NSObject
2 {
3 NSString *_name;
4 }
5 -(void) setName:(NSString*)name;
6 -(NSString*) name;
7 @end
8
9 @implementation myClass
10 -(void) setName:(NSString*)name
11 {
12 _name = name;
13 }
14 -(NSString*) name
15 {
16 return _name;
17 }
18 @end
19 int main(int argc, const char * argv[]) {
20 @autoreleasepool {
21 myClass *mc = [[myClass alloc] init];
22 [mc setName:@"hello"];
23 NSLog([mc name]);
24 }
25 return 0;
26 }
1.2 property方式
若使用@property关键字,则自动生成_name的成员变量,以及setName和name方法。
1 @interface myClass : NSObject
2 @property NSString* name;
3 -(void) myMethod;
4 @end
5 @implementation myClass
6 -(void) myMethod
7 {
8 NSLog(_name);
9 }
10 @end
11 int main(int argc, const char * argv[]) {
12 @autoreleasepool {
13 myClass *mc = [[myClass alloc] init];
14 [mc setName:@"hello"];
15 NSLog([mc name]);
16 }
17 return 0;
18 }
在Object-C中是不能像C/C++一样使用点表达式直接访问对象中的属性,需要通过消息进行访问。但通过@property就能够直接访问对象中的属性来。比如上述的AllWeatherRadial类:
AllWeatherRadial *a = [ [AllWeatherRadial alloc] init ]; [a setRainHandling:23]; NSLog(@“%f”, a.RainHandling );
2、@synthesize关键字
通过@property关键字声明的属性,编译器会自动生成一个实例变量,该变量的名字是在属性名前加下划线。可以使用@synthesize关键字从新指定实例变量的名字,即在@implementation文件中的某个方法使用的属性名,其有两种使用形式:
2.1 属性名形式
可以在@implementation文件中再此声明@property中定义的属性名,从而在@implementation中的方法只能使用@property定义的属性名,而不是在属性名前加下划线的名字。如下所示:
1 @interface myClass : NSObject
2 @property NSString* name;
3 -(void) myMethod;
4 @end
5 @implementation myClass
6 @synthesize name;
7
8 -(void) myMethod
9 {
10 NSLog(name);
11 //NSLog(_name);若是这种形式,则编译器报错
12 }
13 @end
14 int main(int argc, const char * argv[]) {
15 @autoreleasepool {
16 myClass *mc = [[myClass alloc] init];
17 [mc setName:@"hello"];
18 [mc myMethod];
19 }
20 return 0;
21 }
2.2 重命名形式
若不希望在@implementation的方法中使用属性命名的实例变量,也不希望使用下划线命名的实例变量,可以自定义自己希望的名字,同样是使用@property关键字。
1 @implementation myClass
2
3 @synthesize name=myName;
4
5 -(void) myMethod
6 {
7 NSLog(myName); //不能使用其它形式,如使用了_name或name,则编译器会报错
8 }
9 @end
3、@dynamic关键字
若不希望编译器自动生成实例变量名和存取方法,则可以使用@dynamic关键字在@implementation文件中进行声明。
1 @interface myClass : NSObject
2 @property NSString* name;
3 -(void) myMethod;
4 @end
5 @implementation myClass
6 @dynamic name;
7 -(void) myMethod
8 {
9 NSLog(name); //编译器将报错
10 }
11 @end
4、属性特质
@property还可以设置属性的各种特质(attribute),从而影响编译器自动生成的setter和getter方法,其使用语法为:
@property (参数1,参数2) 类型 名字;
表格 31 属性特质
|
参数 |
意义 |
|
|
原子性 |
atomic (默认) |
保证多线程访问下的安全, 但浪费系统资源, 原子性控制的默认设置. |
|
nonatomic |
禁止多线程,变量保护,提高性能。 |
|
|
读写属性 |
readwrite (默认) |
产生setter\getter方法。 |
|
readonly |
只产生简单的getter,没有setter, 默认的读写属性. |
|
|
内存管理 |
assign |
默认类型,为简单赋值,不更改引用计数,适用于标亮数据类型(scalar type);对对象类型,同样不会改变引用计数值。 |
|
strong (默认) |
该类型属性定义了一种"拥有关系",编译器会生成的setter方法会修改引用计数值。先增加新值的引用计数,再减少旧值的引用计数。 |
|
|
weak |
该类型属性定义了一种"非拥有关系",编译器生成的setter方法不会修改引用计数值,即不会增加引用计数,也不会减少引用计数。此特质与assign类似,然而当该属性被系统释放时,所有引用该对象的指针都会被置为nil。 |
|
|
unsafe_unretained |
该类型与assign类似,定义了一种"非拥有关系",同样不修改引用计数,当目标对象被释放时,所有引用该对象的指针不会被置为nil。 |
|
|
copy |
该类型与strong类似,然而该类型的setter方法并不会增加新值的引用计数,而是会创建一个新的对象(引用计数为1)。 |
|
|
retain |
与strong相对应,使用了引用计数,retain+1,release -1;当引用计数为0时,dealloc会被调用,内存被释放。 |
|
|
方法名 |
setter = |
指定生成setter方法的名字。 |
|
getter = |
指定生成getter方法的名字。 |
|
4.1 原子性
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。
- atomicity:当属性声明为atomic时,意味着在多线程中只能有一个线程能对它进行访问,默认为原子类型。
- nonatomic:当属性声明为nonatomic时,意味着多个线程可以同时对其进行访问,所以访问速度较快.
4.2 读写权限
- readwrite(读写):拥有该特质的属性编译器会自动生成"获取方法"(getter)与"设置方法"(setter)。
- readonly(只读):拥有该特质的属性编译器只生成"获取方法"(getter)。Readonly特质不生成setter方法,所以它不可以和 copy/retain/assign组合使用。
4.3 内存管理
内存管理的6种属性特质中,可以分为ARC和非ARC类型:
- ARC类型:assign、strong、weak、unsafe_unretained、copy。
- 非ARC类型:retain。
面试题:
1) strong与weak的区别
strong类型的属性是一种拥有关系,即当调用strong类型属性的setter方法时,被传递参数的引用计数为+1,而原来属性值的引用计数会-1;而weak类型是一种非拥有关系,即当调用weak类型属性的setter方法时,不会修改任何引用计数,同时但weak属性被释放时,所有引用该对象的指针都会被置为nil。
2) assign、copy及retain的区别
- assign:该类型的属性可以理解为C++中的指针类型,即没有引用计数的概念,有可能出现访问野指针的情况。
- retain:该类型的属性拥有引用计数,当调用该类型属性的setter方法时,会改变原来属性对象的引用计数,也会改变新传递参数的引用计数。
- copy:该类型的属性也拥有引用计数,但当setter该属性时,不修改所传递参数的引用计数,只是复制了该参数(创建新的对象),从而新创建对象的引用计数为1。
4.4 方法名
- setter=<name>:指定"设置方法"的方法名,这种用法不太常见。
- getter=<name>:指定"获取方法"的方法名。
面试题:
1) 在一个对象的方法里面:self.name = "object"和name ="object"的区别?
self.name = "object"会调用对象的setName()方法,而name = "object"会直接把object赋值给当前对象的name 属性。并且若name属性声明为strong或retain类型的特质,则 self.name 的retainCount会加1,而name就不会。
Objective-C:属性(@property)的更多相关文章
- 区分元素特性attribute和对象属性property
× 目录 [1]定义 [2]共有 [3]例外[4]特殊[5]自定义[6]混淆[7]总结 前面的话 其实attribute和property两个单词,翻译出来都是属性,但是<javascript高 ...
- 属性(@property)、@synthesize
先前我们学的实例变量是这样的 { int _age; int _height; int age; } 后来学属性 @property int age; 看到@property 会自动编译生成某个成员变 ...
- Object的属性property详细解释(自动生成成员变量)
类Class中的属性property: 在ios第一版中,我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: @interfac ...
- OC 实例变量(instance var)与属性(@property)的关系 isa指针
实例变量(instance var)与属性(@property)的关系 Objective-C 2.0之后,声明一个@property name自动产生一个实例变量,名为_name,因此省去实例变量和 ...
- iOS中属性Property的常用关键字的使用说明
属性关键字的作用 现在我们iOS开发中,基本都是使用ARC(自动引用计数)技术,来编写我们的代码.因此在属性property中我们经常使用的关键字有strong,weak,assign,copy,no ...
- Effective C# 学习笔记(原则一:始终能的使用属性(property),而不是可直接访问的Data Member)
原则一:始终能的使用属性(property),而不是可直接访问的Data Member Always use properties instead of accessible data memb ...
- 对用户控件(ascx)属性(property)赋值
对用户控件(ascx)属性(property)赋值 Insus.NET写此博文,是对用户控件(ASCX)的属性赋值经验与技巧分享.是这样子的,在做新闻站点时,一般都会有分很多类别. 在站点首页会显示最 ...
- Yii2基本概念之——属性(property)
学习任何一门学问,往往都是从起基本的概念学起.万丈高楼平地起,这些基本概念就是高楼的基石,必须做详尽的分析.我们知道,Yii2是一款脉络清晰的框架,理顺了基础的概念和基本功能,学习更高级和复杂的功能就 ...
- Day8 封装 静态属性property
封装:将类的属性隐藏 #先看如何隐藏 1,在定义的属性之前加入__. class Foo: __N=111111 #_Foo__N def __init__(self,name): self.__Na ...
- 理解特性attribute 和 属性property的区别 及相关DOM操作总结
查一下英语单词解释,两个都可以表示属性.但attribute倾向于解释为特质,而property倾向于解释私有的.这个property的私有解释可以更方便我们下面的理解. 第一部分:区别点 第一点: ...
随机推荐
- MySQL驱动阅读------executeQuery查询的过程,基于JDBC-----5.1.26
Statement statement = connection.createStatement(); final ResultSet resultSet = statement.executeQue ...
- ZooKeeper系列之八:ZooKeeper的简单操作
http://blog.csdn.net/shenlan211314/article/details/6187035 1 )使用 ls 命令来查看当前 ZooKeeper 中所包含的内容: [zk: ...
- 我所理解的OOP——UML六种关系(转)
转自:http://www.cnblogs.com/dolphinX/p/3296681.html 最近由于经常给公司的小伙伴儿们讲一些OOP的基本东西,每次草纸都被我弄的很尴尬,画来画去自己都乱了, ...
- QPixmap有缓冲区的
我想qt 中QPixmap这个类大家都很熟悉,它可以很简单的在标签上贴图:例如: QPixmap p; p.load("1.png"): label->setPixmap(p ...
- java数组遍历——iterator和for方法
import Java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ArrayTest ...
- Light OJ 1033 - Generating Palindromes(区间DP)
题目大意: 给你一个字符串,问最少增加几个字符使得这个字符串变为回文串. ============================================================= ...
- ARM 开发板嵌入式linux系统与主机PC通过串口传输文件
本文转载自http://useless20.blog.163.com/blog/static/237409982010227127576/ 嵌入式linux系统与主机通过串口传输文件 我想如果要从PC ...
- 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...
- HDOJ/HDU 2535 Vote(排序、)
Problem Description 美国大选是按各州的投票结果来确定最终的结果的,如果得到超过一半的州的支持就可以当选,而每个州的投票结果又是由该州选民投票产生的,如果某个州超过一半的选民支持希拉 ...
- MVC5 学习整理
一.概述 MVC简介: • 模型(Model) “数据模型”(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法.“模型”有对数据直接访问的权力,例如对数据库的访问.“ ...