属性(@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

3 @synthesize name=myName;

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就不会。

时间: 2024-11-03 03:47:38

属性(@property)的相关文章

Objective-C基础5 : 属性@property

1.类里面经常有一些变量需要进行set和get操作,OC中提供了方便的属性@property来替换set和get方法,这样能减少频繁且简单的重复代码.如下代码: @interface Person : NSObject @property NSString* strName; @property int nAge; @end @implementation Person @synthesize strName; @synthesize nAge; @end 通过在类声明变量前面添加@proper

作为笔记:Objective-C属性property的一些认识

在头文件中声明: @property (nonatomic,strong) NSString * str; 在oc中,这一行代码表示一个名为str的属性. 在实现文件.m中声明: @synthesize str; 在oc中类中声明了这一句话就会自动生成两个方法(生成属性的getter和setter),一个属性,如果实现了属性(在.m文件中)则会生成一个实例变量. 在类别中声明了了属性则会自动生成两个方法,则必须实现setter和getter,类别中属性要用@dynamic,但是不会生成实例变量.

python静态属性----property

1.什么是静态属性property property是一种特殊的属性,访问它的时候会执行一段功能(函数)然后返回值. 在使用者直接要某个结果的时候,就需要用到了静态属性. 2.例子 计算BMI指数. class People: def __init__(self,name,tz,hit): self.name=name self.tz=tz self.hit=hit @property def bmi(self): return self.tz / (self.hit**2) p=People(

属性(property)与成员变量(ivar)

类内使用成员变量{}, 类外使用属性@property /*********** --- Person.h */ @interface Person : NSObject { NSString *_name; } @property (nonatomic, copy) NSString *sex; @property (nonatomic, assign) int age; - (void)getPropertyAndiVar; @end /*********** --- Person.m */

iOS runtime探究(三): 从runtime开始理解OC的属性property

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属

实例变量(instance var)与属性(@property)的关系

实例变量(instance var)与属性(@property)的关系 Objective-C 2.0之后,声明一个@property name自动产生一个实例变量,名为_name,因此省去实例变量和属性重复输入的麻烦.而使用@synthesize可以改变_name名称.@property和@synthesize不必成对出现. @property name:指示编译器自动合成setter和getter方法,setter方法名即setName,而getter方法名即name.@property后面

属性( @property )与成员变量的那些事 :

属性( @property )与成员变量的那些事 : 属性对成员变量扩充了存取方法 . 属性默认会生成带下划线的成员变量 . 早期的 Xcode 不支持自动合成成员变量的存取方法 , 所以古老的iOS工程师是愤怒的 . 后来 Xcode 智能了一点 , 可以用 @synthesize 关键字自动合成成员变量的存取方法 , 此时的iOS工程师是郁闷的 . 现在 Xcode 会在我们声明属性时自动合成存取方法 , 连@synthesize都不用写了 , 这样iOS工程师彻底解放了 . 顺便提一下 @

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

其实attribute和property两个单词,翻译出来都是属性,但是<javascript高级程序设计>将它们翻译为特性和属性,以示区分.本文将详细介绍特性和属性的不同之处 定义 元素特性attribute是指HTML元素标签的特性 下面的id.class.title.a都是特性,其中a叫做自定义特性 <div id="id1" class="class1" title="title1" a='a1'></div

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

原则一:始终能的使用属性(property),而不是可直接访问的Data Member    Always use properties instead of accessible data members. 为什么要使用属性: 1.Net的data binding只支持Property,而不支持public data member的访问 Data binding的目的就是把一个object的Property绑定到一个用户界面的control上,web control或者windows form

5 属性 property

1.属性  property 调用私有属性通过实例方法调用.达到这种效果 #property的作用:相当于把方法进行了封装, 开发者在对属性设置数据的时候更方便 class Dog(object): def __init__(self): self.__num = 100 def set_num(self,new_num): print("---setter") self.__num = new_num def get_num(self): print("----getter