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的私有解释可以更方便我们下面的理解. 第一部分:区别点 第一点: ...
随机推荐
- Linux下的echo服务器
epoll模式下的echo服务器,忘记从哪个网页上粘贴过来的了,学习一下 /* * main.cc * * Created on: 2009-11-30 * Author: liheyuan * De ...
- C语言头文件的作用
C99中规定, 所有顶层的默认存储类标志符都是extern ! 头文件中声明的函数,默认都是extern前缀.但是为了我们程序员方便,我们采取下面的手段: 我个人认为是extern催生了头文件的诞生. ...
- 运行时改变控件的大小(点击后立刻ReleaseCapture,然后计算位移,最后发消息改变位置)——最有趣的是TPanel其实也有窗口标题,因此可发HTCAPTION消息
//光标在控件不同位置时的样式 // 由于拐角这点手动精确实在困难 所以用范围 范围+3 这样很容易就找到这一点了 procedure CtrlMouseMove(Ctrl: TWinControl; ...
- Storm学习笔记
1.如何让一个spout并行读取多个流? 方法:任何spout.bolts组件都可以访问TopologyContext.利用这个特性可以让Spouts的实例之间划分流. 示例:获取到storm集群sp ...
- 《Effective C++》内存管理
如果global new-hander没有成功配置,会抛出一个std::bad_alloc的exception. #include<iostream> #include<new> ...
- 14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率:
14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率: 主线程 在InnoDB 是一个线程 执行各种任务在后台. ...
- WPF 界面布局DockPanel stackPanel WrapPanel 元素内容以及位置控制
1 DockPanel 1) 默认充满整个窗口. 2) 最后一个出现的部分,默认充满剩余空间. 3) 非最后一个出现的部分,根据其中内容,进行分配空间s 2 StackPanel 实现居左,居右,居中 ...
- web版本控制
说说你在web开发中是怎么进行版本管理的 在web开发中,我首先将系统框架搭建完成后,我会发布到服务器上,然后给小组成员进行分工,为他们划分各自的模块,他们每天早上上班时就从服务器上先将自己机器上面的 ...
- java学习面向对象之多态
如何理解多态,让我们举个例子来描述一下,因为单纯的说多态大家可能不理解: abstract class Animal { ; abstract void eat(); public void run( ...
- vijosP1779国王游戏
题目:https://vijos.org/p/1779 题解:忽然想起来我好像还没写过高精度除以单精度,于是拿这题练练手...没想到1A了... 代码: #include<cstdio> ...