您的位置:首页 > 移动开发 > IOS开发

iOS成员变量、成员属性和点语法

2016-03-12 12:21 363 查看

1、成员变量

< 实例变量+基本数据类型变量 =成员变量 >

在接口 @interface 大括号里面的统称为“成员变量”,除去基本数据类型int float ....等,其他类型的变量都叫做实例变量。系统会为成员变量默认初始化,基本类型变量默认被初始化为0,实例变量默认被初始化为nil。

实例变量的英文翻译是 Instance Variable (object-specific storage)
实例的英文翻译为Instance(manifestation of a class)说的是“类的表现”,说明实例变量是由类定义的变量!

成员变量的作用域:

 @public :在任何地方都能直接访问对象的成员变量。
 @protected :可以在当前类及其子类的对象方法中直接访问。(@interface中默认是@protected)
 @private :只能在当前类的对象方法中直接访问。(@implementation中默认是@private)

2、成员属性

在@property(描述1 , 描述2 , 描述3)(class *) varName 里面,有3个描述词需要填写(也可以不填写取默认值)

nonatomic<-->atomic  原子属性:atomic/nonatomic,nonatomic禁止多线程,变量保护提高性能
readwrite<-->readonly  读写属性:readwrite/readonly,readonly关键字代表setter不会被生成,所以它不可以和 copy/retain/assign组合使用
retain/copy/assign  内存属性:assign/retain/copy/strong,copy是内容拷贝,retain是指针拷贝

详细说明:

1.atomic与nonatomic

atomic:默认是该属性,这个属性是为了保证程序在多线程情况,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。
nonatomic:如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。

2.readwrite与readonly

readwrite:这个属性是默认的情况,会自动为你生成存取器。
readonly:只生成getter不会有setter方法。
readwrite、readonly这两个属性的真正价值,不是提供成员变量访问接口,而是控制成员变量的访问权限。

3.assign、copy、retain

assign:默认类型,setter方法直接赋值,不进行任何retain操作,不改变引用计数。一般用来处理基本数据类型。
 retain:释放旧的对象(release),将旧对象的值赋给新对象,再令新对象引用计数为1。我理解为指针的拷贝,拷贝一份原来的指针,释放原来指针指向的对象的内容,再令指针指向新的对象内容。他指的是将某个内存区域的指针赋值给变量,同时把该内存区域的引用计数器加1。每执行一次,该内存区域的引用计数器就要加1,当该区域的引用计数器变为0的时候内存区域被释放!
copy:与retain处理流程一样,先对旧值release,再copy出新的对象,retainCount为1.为了减少对上下文的依赖而引入的机 制。我理解为内容的拷贝,向内存申请一块空间,把原来的对象内容赋给它,令其引用计数为1。对copy属性要特别注意:被定义有copy属性的对象必须要 符合NSCopying协议,必须实现- (id)copyWithZone:(NSZone *)zone方法。它指的是将目标内存区域的值复制一份,然后开辟新的内存区域(新的指针)粘贴这个值。同时变量被赋值为新内存区域的指针!

4.strong与weak

strong与weak是由ARC新引入的对象变量属性,ARC引入了新的对象的生命周期限定,即零弱引用。如果零弱引用指向的对象被deallocated的话,零弱引用的对象会被自动设置为nil。
强引用与弱引用的广义区别:
强引用也就是我们通常所讲的引用,其存亡直接决定了所指对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放。弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那么其还是会被清除。

简单讲,strong等同retain,weak比assign多了一个功能,当对象消失后自动把指针变成nil。

使用

 使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)
 使用copy: 对NSString
 使用retain: 对其他NSObject和其子类

3、类别中使用属性

类别中只能添加方法,不能添加实例变量。 经常会在ios的代码中看到在类别中添加属性,这种情况下,是不会自动生成实例变量的。 比如:

@interface UIViewController(UINavigationControllerItem)
@property(nonatomic) BOOL hidesBottomBarWhenPushed;
@property(nonatomic,readonly,retain)UINavigationControlle*navigationController;
@end


 这里添加的属性,不会自动生成实例变量,这里添加的属性其实是添加的getter与setter方法。属性在.h文件中和在.m中声明是有区别的。区别就是,在.h文件中声明的属性,外部类可以通过“类实例.属性”来调用,但在.m中声明的则不可以,获取和设置的方法,只能是通过setValue:forKey和valueForKey来实现。

4、点语法

在oc中点表达式其实就是调用对象的setter和getter方法的一种快捷方式,如果点表达式出现在等号“ =” 左边,该属性名称的setter方法将被调用,如果点表达式出现在右边,该属性名称的getter方法将被调用 。
以前的用法,声明属性跟与之对应的实例变量:

@interface MyViewController :UIViewController
{

UIButton *myButton;

}

@property (nonatomic, retain) UIButton *myButton;

@end


这种方法基本上使用最多,现在大部分也是在使用,因为很多开源的代码都是这种方式。 但是ios5更新之后,苹果是建议以以下的方式来使用

@interface MyViewController :UIViewController

@property (nonatomic, retain) UIButton *myButton;
@end


因为编译器会自动为你生成以下划线开头的实例变量_myButton。不需要自己手动再去写实例变量, 而且也不需要在.m文件中写@synthesize myButton,也会自动为你生成setter、getter方法。

@synthesize的作用就是让编译器为你自动生成setter与getter方法。 它还有一个作用,可以指定与属性对应的实例变量

例如@synthesize myButton = xxx; 那么self.myButton其实是操作的实例变量xxx,而不是_myButton了。 在实际的项目中,我们一般这么写.m文件
@synthesize myButton; 这样写了之后,那么编译器会自动生成myButton的实例变量,以及相应的getter和setter方法。 注意: _myButton这个实例变量是不存在的,因为自动生成的实例变量为myButton而不是_myButton。 所以现在@synthesize的作用就相当于指定实例变量,如果.m文件中写了@synthesize
myButton;那么生成的实例变量就是myButton。 如果没写@synthesize myButton;那么生成的实例变量就是_myButton。

 sythesize使用示例:

.h
@property (automic,retain) NSString * aString;
.m
@sythesize aString;


在写了@sythesize aString;的情况下,系统不会自动生成实例变量“_aString“,直接通过变量名aString ,也就是直接使用变量名在赋值运算的时候(=号左边),只是将内存区域的指针赋值给变量,相当于assgin 。 如果是通过“点语句”self.aString= 来赋值,就要看在@property中定义的是copy、retain、assign哪一种了,如果没有加上上述描述词,就默认为assign。
如果没有写@sythesize aString;  系统会默认自动在.h文件{}中添加一个不可见的加“_”的成员变量(即使是变量名中本身就带有“_”)
括号里面定义的都是成员变量(基本数据类型+类生成变量),里面的变量可以在.m文件中通过“变量名称”、self->“变量名称”直接访问到括号
bc79
里面的变量,但是,这样的赋值访问只能是assign,原对象的引用计数器不会发生变化。

@sythesize 变量名;2.@sythesize 变量名=_变量名;3.不写@sythesize (以下提到的变量名都是指的在头文件中@property 中定义的变量)

1.成员变量,实例变量通过“变量名”或者self->“变量名”直接访问到,赋值(assign)。self.变量名 实现setter,getter方法。
2.成员变量,实例变量通过“_变量名”或者self->“_变量名”直接访问到,赋值(assign)。self.变量名 实现setter,getter方法。
3.成员变量。实例变量(系统自动在原来变量名前加上“_”来生成的实例,成员变量),直接通过self->_变量名,或者变量名直接访问到(assign)。self.变量名 实现setter,getter方法。

注意:

retaincopyassign都是指的,在自动生成setter函数的时候,编译器需要识别个描述词来生成对应的setter函数!需要注意的是,如果没有加上该类的描述词,系统默认该变量的setter方法采取assign的方式。

retain 表示对NSObject和及其子类对象release旧值,再retain新值,使对象的应用计数增加一。

此属性只能使用于obejective-c类型对象,而不能用于Core Foundation对象。(retain会增加对象的引用计数,而基本数据类型或者Core
Foundation对象都没有引用计数,把对象添加到数组中时,引用计数将增加1)。

- (void) setOldValue: (NSString*) newValue {

    if (newValue !=oldValue) {

        [oldValue release];

        oldValue = [newValue retain];

    }

}

assign 是默认属性,只可以对基本数据类型(如CGFloat,NSInteger,Bool,int,代理对象)等使用。该方式会对对象直接赋值而不会进行retain操作。

copy 表示重新建立一个新的计数为1的对象,然后释放掉旧的值。

都知道retain是对指针的拷贝,copy是对内容的拷贝。比如:NSString
对象的地址为0x100,其内容为“string”,如果使用copy到另外一个NSString对象,则会生成另外一个地址为0x110的对象,只不过内容仍然是‘string“。如果使用retain到另外一个NSString对象,则该对象的地址仍然为0x100,只不过该对象的计数变为2.

strong与weak是由ARC新引入的对象变量属性

ARC引入了新的对象的生命周期限定,即零弱引用。如果零弱引用指向的对象被deallocated的话,零弱引用的对象会被自动设置为nil。

强引用与弱引用的广义区别:

强引用也就是我们通常所讲的引用,其存亡直接决定了所指对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放。

弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那么其还是会被清除。

简单讲,strong等同retain,weak比assign多了一个功能,当对象消失后自动把指针变成nil。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息