@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)的更多相关文章

  1. 区分元素特性attribute和对象属性property

    × 目录 [1]定义 [2]共有 [3]例外[4]特殊[5]自定义[6]混淆[7]总结 前面的话 其实attribute和property两个单词,翻译出来都是属性,但是<javascript高 ...

  2. 属性(@property)、@synthesize

    先前我们学的实例变量是这样的 { int _age; int _height; int age; } 后来学属性 @property int age; 看到@property 会自动编译生成某个成员变 ...

  3. Object的属性property详细解释(自动生成成员变量)

    类Class中的属性property: 在ios第一版中,我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: @interfac ...

  4. OC 实例变量(instance var)与属性(@property)的关系 isa指针

    实例变量(instance var)与属性(@property)的关系 Objective-C 2.0之后,声明一个@property name自动产生一个实例变量,名为_name,因此省去实例变量和 ...

  5. iOS中属性Property的常用关键字的使用说明

    属性关键字的作用 现在我们iOS开发中,基本都是使用ARC(自动引用计数)技术,来编写我们的代码.因此在属性property中我们经常使用的关键字有strong,weak,assign,copy,no ...

  6. Effective C# 学习笔记(原则一:始终能的使用属性(property),而不是可直接访问的Data Member)

    原则一:始终能的使用属性(property),而不是可直接访问的Data Member    Always use properties instead of accessible data memb ...

  7. 对用户控件(ascx)属性(property)赋值

    对用户控件(ascx)属性(property)赋值 Insus.NET写此博文,是对用户控件(ASCX)的属性赋值经验与技巧分享.是这样子的,在做新闻站点时,一般都会有分很多类别. 在站点首页会显示最 ...

  8. Yii2基本概念之——属性(property)

    学习任何一门学问,往往都是从起基本的概念学起.万丈高楼平地起,这些基本概念就是高楼的基石,必须做详尽的分析.我们知道,Yii2是一款脉络清晰的框架,理顺了基础的概念和基本功能,学习更高级和复杂的功能就 ...

  9. Day8 封装 静态属性property

    封装:将类的属性隐藏 #先看如何隐藏 1,在定义的属性之前加入__. class Foo: __N=111111 #_Foo__N def __init__(self,name): self.__Na ...

  10. 理解特性attribute 和 属性property的区别 及相关DOM操作总结

    查一下英语单词解释,两个都可以表示属性.但attribute倾向于解释为特质,而property倾向于解释私有的.这个property的私有解释可以更方便我们下面的理解. 第一部分:区别点 第一点:  ...

随机推荐

  1. Linux下的echo服务器

    epoll模式下的echo服务器,忘记从哪个网页上粘贴过来的了,学习一下 /* * main.cc * * Created on: 2009-11-30 * Author: liheyuan * De ...

  2. C语言头文件的作用

    C99中规定, 所有顶层的默认存储类标志符都是extern ! 头文件中声明的函数,默认都是extern前缀.但是为了我们程序员方便,我们采取下面的手段: 我个人认为是extern催生了头文件的诞生. ...

  3. 运行时改变控件的大小(点击后立刻ReleaseCapture,然后计算位移,最后发消息改变位置)——最有趣的是TPanel其实也有窗口标题,因此可发HTCAPTION消息

    //光标在控件不同位置时的样式 // 由于拐角这点手动精确实在困难 所以用范围 范围+3 这样很容易就找到这一点了 procedure CtrlMouseMove(Ctrl: TWinControl; ...

  4. Storm学习笔记

    1.如何让一个spout并行读取多个流? 方法:任何spout.bolts组件都可以访问TopologyContext.利用这个特性可以让Spouts的实例之间划分流. 示例:获取到storm集群sp ...

  5. 《Effective C++》内存管理

    如果global new-hander没有成功配置,会抛出一个std::bad_alloc的exception. #include<iostream> #include<new> ...

  6. 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 是一个线程 执行各种任务在后台. ...

  7. WPF 界面布局DockPanel stackPanel WrapPanel 元素内容以及位置控制

    1 DockPanel 1) 默认充满整个窗口. 2) 最后一个出现的部分,默认充满剩余空间. 3) 非最后一个出现的部分,根据其中内容,进行分配空间s 2 StackPanel 实现居左,居右,居中 ...

  8. web版本控制

    说说你在web开发中是怎么进行版本管理的 在web开发中,我首先将系统框架搭建完成后,我会发布到服务器上,然后给小组成员进行分工,为他们划分各自的模块,他们每天早上上班时就从服务器上先将自己机器上面的 ...

  9. java学习面向对象之多态

    如何理解多态,让我们举个例子来描述一下,因为单纯的说多态大家可能不理解: abstract class Animal { ; abstract void eat(); public void run( ...

  10. vijosP1779国王游戏

    题目:https://vijos.org/p/1779 题解:忽然想起来我好像还没写过高精度除以单精度,于是拿这题练练手...没想到1A了... 代码: #include<cstdio> ...