OC中@property属性关键字的使用(assign/weak/strong/copy)

一、assign

用于 ‘基本数据类型’、‘枚举’、‘结构体’ 等非OC对象类型

eg:int、bool等

二、 weak

1. 一般应用: UI控件

2. 详细说明:

(1)为什么建议UI控件一般使用weak?首先我们从controller来看,controller是被系统用强指针引用着,所以如果 controller 还存在,里面的子控件也会存在,那么controller 强引用着它的view(从 controller 中它的 view 的属性是 retain 看出来的,retain 就是 MRC 年代的强引用),那么 view 又强引用着它的数组对象subviews,数组对象又引用着它所包含的数组内容,所以当我们创建出来一个UI控件并将其加入到subviews的时候,它就会被一个强指针所引用着,我们可以简化一下这个过程:--> Controller --> View --> Subviews(数组) --> 数组内容(添加到其中的UI控件)

(2)清楚了过程之后,我们来看我们所创建的对象,如果我们所创建的是一个临时变量的话,那么当出去作用域之后对象就被销毁,但是这里请注意,这里分为两个内存空间,一个是对象的内存空间,一个是指针的内存空间,如果创建的是临时变量的话,一旦出了作用域那么我们的指针内存是被清空了,但是我们的内容如果加到了subviews中,就会被subviews强引用,那么我们的控件就还会存在,只不过是一个指向它的指针被清空了而已。

(3)回过头我们说说全局变量,全局变量的话,指针会一直存在,这里面谈谈为什么要用weak,其实只要我们创建的控件加入到subviews中去的话,那么这个控件就会一直存在,所以在这里我们所创建的指针是weak或strong其实只不过是多一个实线虚线的问题,也就是控件已经被强引用了,你再给它添加一个强引用或者弱引用在使用上都不会有什么问题,但是问题来了,如果我们remove了这个控件,我们subViews中的那根线被切断,也就是这个代表我不再需要这个控件了,那么这个时候如果再用一个strong来连接它,那么对象就不会被清除,既然我们都不需要它了,为什么我还强引用它?这也就是为什么我们再这里用弱引用的原因。`简言之,就是内存使用上的合理性,当这个控件我们需要的时候其实已经有一个强引用在引用着它,我们没有必要再弄一根指针来强引用着它,当我们不需要它的时候,如果是weak的话自然而然直接释放掉了,如果strong的话还会保留它,既然我们没用了我们为什么还要留着它而占用我们宝贵的内存呢?我们也可以看一下这张图片用来理解:

(4)这里特殊说一下IBOutlet中的拖线创建,我们可以发现,如果用storyboard或者xib进行的脱线创建,苹果都会自动降属性置为weak,这种做法似乎也符合我们之前的说法,但是苹果又会在之前加了一个IBOutlet这个关键词,那么这个词是什么意思呢?我们看一下苹果的官网解释: The symbol IBOutlet is used only by Xcode, to determine when a property is an outlet; it has no actual value. 意思很清楚了,它仅仅是指定了一个属性是一个 外部设置的,并没有实质的含义,通常与外界连接是通过当前的 viewcontroller 。那么在引用上又有什么不同呢?在官方文档中是这么说的,在我们创建了IBOutlet之后,我们系统会有一个自动对它进行一个强引用,也就是又多了一条实线连接着它,当控件从我们的subviews中移除之后,这条线会自动判断去留,也就是不会对我们的内存的性能造成影响,该在的时候我在,该消失的时候自己就会消失了。这里也用一张图来说明:

在我写demo的时候有一点需要注意,就是当我们将控件从subViews中remove调之后,这个时候打印指针还存在,说明指针并不会马上销毁,而是进行下一轮消息循环之后才会发现这个指针被销毁了.

3. 总结:

我们首先是从内存的利用上,我们建议对UI控件采用weak,其次是观察苹果的声明方式,依然是建议使用weak,因为标准都是参考于苹果,而且合理性也摆在那里,为什么不用呢?

三、
strong

OC对象类型(NSArray、NSDate、NSNumber、模型类)

一个对象只要有强指针引用着,就不会被销毁

四、
copy

1. 一般用在NSString*类型、block类型上

2.  copy语法的作用:产生副本。 且copy返回的是不可变的副本,mutableCopy返回的是可变的副本。

3. 修改了副本并不会影响源对象,修改了源对象,并不会影响副本。

4. copy在属性声明中的使用,直接举例说明

@interface ViewController ()//注意这里虽然是copy的属性,但是我们这个指针还是强引用的

@property(nonatomic,copy)NSString*name;

@end

@implementation Viewcontroller

-(void)viewDidLoad

{

[self viewDidLoad];

NSMutableString*str = [NSMutableString
stringWithFormat:@"aaa"];

self.name = str;

[str appendString:@"bbb"];

NSLog(@"str= %@",str);

NSLog(@"name =
%@",self.name);

NSLog(@"%p,%p",str, self.name);

}

@end

我们来看一下说出的结果:

str = aaabbb

name = aaa

输出的内存地址:0x7f90f3028180 , 0x7f90f3027450

这说明了这个copy的含义就是,我们在给name属性赋值的时候,,系统默认先将str执行一次copy方法,然后再将结果赋给我们的属性,只有这样你再之后对str修改之后,name的值还是不变的,说明两个指针其实指向的是不同的内容,之后我们又打印了我们的指针值,得出不同的结果又证明了上述所说。

5. 注意:并不是所有情况下我们的string都必须使用copy,因为如果我们的需求是希望string是随着我的改变而改变的,那么这个时候应该使用strong。

6. 类的copy:

如果我们想实现类的copy,必须实现一个方法:-(id)copyWithZome:(NSZone*)zone; 这是为什么呢?我们去 NSString 中去寻找答案,那么我们会发现其实 NSString 已经遵守了 NSCopying 与 NSMutableCopying 的协议,我们主要看 NSCopying ,进入这个协议之后你会发现 -(id)copyWithZome:(NSZone*)zone 这个方法,也就是说NSString
已经遵守了协议的这个方法,所以才能直接实现 copy 的方法。所以如果想实现自定义类的 copy 方法,我们是需要先遵守 NSCopying 协议,然后实现-(id)copyWithZome:(NSZone*)zone的方法:

-(id)copyWithZone:(NSZone *)zone

{

Mitchell*copyMit = [[Mitchell
allocWithZone:zone] init];

copyMit.name = self.name;return copyMit;

}

zone:系统返回给我们 copy 对象的内存空间

注意:必须在初始化方法中给属性赋值,才能让 copy 出的对象和原来的对象有相同的属性。

7. 再说一下 copy 类中的 set 方法,如果属性是 copy
的,那么系统默认只会在 set 方法中调用 copy 的方法:

-(void)setName:(Mitchell*)name

{

_name = [name copy];

}

OC中@property属性关键字的使用(assign/weak/strong/copy)的更多相关文章

  1. @property属性关键字

    关于@property属性关键字使用注意:* weak(assign) :  代理\UI控件* strong(retain) : 其他对象(除代理\UI控件\字符串以外的对象)* copy : 字符串 ...

  2. python 中 property 属性的讲解及应用

    Python中property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回 property属性的有两种方式: 1. 装饰器 即:在方法上应用装饰器 2. 类属性 即 ...

  3. OC中两个关键字的作用:@property和@synthesize

    两个关键字的使用:@property和@synthesize 一.@property关键字这个关键字是OC中能够快速的定义一个属性的方式,而且他可以设置一些值,就可以达到一定的效果,比如引用计数的问题 ...

  4. OC中的属性、方法及内存管理

    普通方法:关注(代表)对象可以”干什么”,过程中需要实例变量.-(void)show;输出 … 访问属性    属性:属性专门处理实例变量.(程序执行过程当中)    初始化方法:一创建对象(第一时间 ...

  5. OC中property方法的使用

    我们直入主题,关于property方法,我们先来了解一下相关的知识,首先是成员变量,实例变量,属性变量. 我们定义一个类来看一下 @interface Person :NSObject{ NSInte ...

  6. python中property属性的介绍及其应用

    Python的property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回. 使用property修饰的实例方法被调用时,可以把它当做实例属性一样 property的 ...

  7. Python中property属性的概论和使用方法

    property属性 概念: 定义一个方法但是使用装饰器property,只可以有一个self形参 可以用这样的属性动态的获取属性的值 定义方式(经典类) class Fun(): @property ...

  8. OC中对于属性的总结(@property)

    在没有属性之前: 对成员变量进行改动都要用到设置器:setter来改动 Person *per =[[Person alloc] init]; 对象通过设置器对成员变量内容进行修该 [per setN ...

  9. OC中property的有关属性

    property的有关属性: (1)readwrite是可读可写特征:需要生成getter方法和setter方法: (2)readonly是只读特性只会生成getter方法不会生成setter方法: ...

随机推荐

  1. 你们以为运营商只是HTTP插点广告而已么?

    国内某邮件服务商,近期在某南方地区有大量客户反应登录时出错和异常,于是工作人员进行了一下跟进,发现如下: 首先,邮件服务商登陆页面为普通HTTP协议发送,提交时通过JS进行RSA加密(没错,JS的RS ...

  2. Redis Cluster 3.0搭建与使用

    Redis Cluster终于出了Stable,这让人很是激动,等Stable很久了,所以还是先玩玩. 一. 集群简单概念. Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施( ...

  3. Task Scheduler Error and Success Constants (Windows)

    If an error occurs, the Task Scheduler APIs can return one of the following error codes as an HRESUL ...

  4. 修改CSV中的某些值 -- 1

    修改前: col1,col2,col3,col4 text1,text2,text3,text4 text5,text6,text7,text8 text9,text10,text11,text12 ...

  5. IMAP命令

    IMAP命令学习1.CREATE <folder>CREATE可以创建指定名字的新邮箱.邮箱名称通常是带路径的文件夹全名.(有些IMAP客户机使用邮件夹称呼新邮箱)C: A003 CREA ...

  6. ci实现RBAC,详细解释原理和核心代码显示

    代码实现不复杂,主要是思路的理解 RBAC是基于权限控制 1.权限结点管理 2.角色管理 3.管理员权限分配 结点管理就是把所有的分组 控制器 方法全部写入一个结点管理表 请注意在写一个动作比如,展示 ...

  7. FZU 2124 bfs+vis记录

    第一次团队训练赛的题 自己看完题没看到不能用舌头吃道具..以为是什么贪心混合bfs..果断放弃..悄悄的背锅了 然后其实比较简单 只是利用vis记录的时候要分两种状态记录 有没有道具 每到一个地方 就 ...

  8. PISCES P4-vSwitch 安装以及一次失败的测试

    本文参考 (1)Varant Download:点我 (2)Mac上安装Git:戳我 (3)Github P4-vSwitch/Varant:点我 (4)Mac强制重新启动:戳我 实验环境: Mac ...

  9. HTTP 笔记与总结(7)HTTP 缓存(配合 Apache 服务器)

    在网络上,有一些缓存服务器,另外浏览器自身也有缓存功能. 例如: <!DOCTYPE html> <html lang="en"> <head> ...

  10. 20145235《Java程序设计》第7周学习总结

    教材学习内容总结 13.1 认识时间与日期 格林威治时间(GMT):通过观察太阳而得,因为地球公转轨道为椭圆形且速度不一,本身自传减速而造成误差. 世界时(UT):通过观测远方星体跨过子午线而得,受地 ...