【IOS开发基础系列】OC基础数据类型使用专题

1 常用数据类型

1.1 @property参数

@property参数分4类

1、读写属性:(readwrite/readonly)

2、setter语意:(assign/retain/copy)

3、原子性:(atomic/nonatomic)

4、引用强弱:(strong/week)


1.1.1 readwrite

     默认属性,将生成不带额外参数的getter和setter方法(setter方法只有一个参数)。


1.1.2 readonly

    只生成get方法


1.1.3 retain

    释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1。

    例如:

    @class Dog

    @property(nonatomic,retain)Dog*dog;


    注:nonatomic与atomic相对应,涉及线程,比较麻烦,这里不做赘述,读者仅需记住,nonatomic相对于atomic来说性能高,而声明属性时一般默认为atomic,故需在此申明nonatomic

    这里使用了retain,那么在set方法中,究竟如何体现的呢?

- (void)setDog:(Dog *)dog

{

   if(_dog !=dog){          //判断是否需要重新赋值

      [_dogrelease];        //释放旧引用,计数器-1

      _dog = [dogretain];   //重新赋值,计数器+1

   }

}


1.1.4 assign

    指定setter方法用简单的赋值,不更改索引计数(Reference Counting),这是默认操作。你可以对标量类型(如int)使用这个属性。你可以想象一个float,它不是一个对象,所以它不能retain、copy。


    例如:

   @property(nonatomic,assign)intcount;

    这里使用了assign,那么在set方法中,究竟如何体现的呢?

- (void)setCount:(int)count

{

   _count = count;

}


1.1.5 copy

    指定应该使用对象的副本(深度复制),前一个值发送一条release消息。基本上像retain,但是没有增加引用计数,是分配一块新的内存来放置它。copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。copy: 建立一个索引计数为1的对象,然后释放旧对象,copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。

例如:

        @property(nonatomic,copy)NSString* str;


这里使用了copy,那么在set方法中,究竟如何体现的呢?

- (void)setStr:(NSString *)str

{

 if(_str != str){          //判断是否需要重新赋值

      [_strrelease];        //释放旧引用,计数器-1

      _str = [strcopy];   //重新赋值,使用copy

   }

}


总结:

     1.retain:先release旧值,再retain新值,在上例中_dog与dog最终指向同一块内存区域。

     2.assign:直接赋值,不考虑内存管理。

     3.copy:Copy其实是建立了一个相同的对象,而retain不是;比如一个NSString对象,地址为0×1111,内容为@”STR”;Copy到另外一个NSString之后,地址为0x2222,内容相同,新的对象retain为1, 旧有对象没有变化。

     4.从retainassign copy的特点中我们可以看出:

     retain一般适用于OC中的对象

     assign一般适用于非OC对象,如int等普通类型

     copycopy一个对象变成新的对象(新内存地址) ,引用计数为1,原来对象计数不变,copy一个对象变成新的对象(新内存地址),引用计数为1,原来对象计数不变。


1.1.6 atomic

    对于对象的默认属性,就是setter/getter生成的方法是一个原子操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter的情况,相关于方法头尾加了锁一样。默认值,保持数据的原子性访问,类似锁。


1.1.7 nonatomic

    不保证setter/getter的原子性,多线程情况下数据可能会有问题。nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。先释放原先变量,再将新变量retain然后赋值;非原子性访问,没加锁,但是提高访问速度,非多线程时访问数据时建议使用。

      注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。


1.1.8 strong

    强引用,ARC模式下与retain同作用,对象的retaincount自动加1


1.1.9 week

    弱引用,ARC模式下与assign同作用,非对象类型使用。


1.2 enum枚举类型

iOS:枚举类型enum,NS_ENUM,NS_OPTIONS

http://blog.csdn.net/annkie/article/details/9877643


2 Catalog使用

2.1 注意问题

2.1.1 Catalog不应履行继承职责,即尽量不要重写源类继承自基类的方法

    Catalog中如果重写基类方法的话,即使其他地方没有引用该类,系统照样会执行进入Catalog类方法中,代码超过了include类的执行范围,容易造成不可预知的异常。

例如:

【IOS开发基础系列】OC基础数据类型使用专题_第1张图片

#import "UIScrollView+UITouch.h"

@implementationUIScrollView (UITouch)


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event {

    [[self nextResponder] touchesBegan:touches withEvent:event];

    [super touchesBegan:touches withEvent:event];

}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent*)event {

    [[self nextResponder] touchesMoved:touches withEvent:event];

    [super touchesMoved:touches withEvent:event];

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent*)event {

    [[self nextResponder] touchesEnded:touches withEvent:event];

    [super touchesEnded:touches withEvent:event];

}

@end

        虽然其他类中没有引用UIScrollView+UITouch.h这个分类类,在触发touch操作时,代码依然会执行到这三个方法中来,因为这个catalog相当于替源类UIScrollView实现了继承的职责,实现了父类的touch方法。自然,就会执行到这个分类类中来,即使没有显式include这个catalog类。


3 参考链接

IOS开发@property中assign、copy、retain等关键字的理解

http://blog.csdn.net/cx_wzp/article/details/47416831

IOS内存管理retain,assign,copy,strong,weak

http://blog.csdn.net/hengshujiyi/article/details/25627131

(Good)Objective-C属性特性(assign , retain , copy , readonly, readwrite , atomic , nonatomic)

http://davychen.blog.51cto.com/3283671/652717

Objective-C的@property详解(ios,iphone,xcode,retain,release,assign,copy)

http://blog.csdn.net/bingxuewujian/article/details/7739358

你可能感兴趣的:(【IOS开发基础系列】OC基础数据类型使用专题)