理解 Objective-c "属性"

@property 是OC中能够快速定义一个属性的关键字,如下我们定义一个属性。

@property	NSString		*String;

这样我们就可以使用这个属性

属性的实质

  • 在属性被加入OC以前我们每次声明一个实例变量都要自己声明并实现存取方法
//
// Created by chao on 15/8/29.
// Copyright (c) 2015 ___FULLUSERNAME___. All rights reserved.
// #import <Foundation/Foundation.h>
@interface Person : NSObject{
NSString *firstName;
NSString *lastName;
} - (void)setFirstName:(NSString *)first;
- (NSString *)firstName;
- (void)setLastName:(NSString *)last;
- (NSString *)lastName;
@end
//在.m文件里实现 #import "Person.h"
@implementation Person {
} - (void)setFirstName:(NSString *)first {
firstName = [first copy];
} - (NSString *)firstName {
return firstName;
} - (void)setLastName:(NSString *)last {
lastName = [last copy];
} - (NSString *)lastName {
return lastName;
} @end

现在有了@property只要简单的声明一下就可以让编译器替我们做以上哪些繁杂的工作。

@property	NSStrinng	*firstNmae;
@property NSString *lastName;
  • 声明属性 编译器除了生成存取方法代码外,还要自动向类中添加适当类型的实例变量。

编译器会自动在属性名之前添加下划线,一次作为实例变量的名字,在上面的声明中会生成两个实例变量

_firstNam, _lastName.我们也可以使用@synthesize语法指定实例变量的名字。

@synthesize firstName   =   _myFirstName; //使用指定的实例变量名称
@synthesize lastName = _myLastName;//如果没有特殊需要尽量使用系统默认的名称
  • 如果不想令编译器合成存取方法, 则可以自己实现,如果只实现了其中一个存取方法, 则另外一个还是会由编译器重新合成,你可以使用@dynamic 关键字阻止编译器自动合成存取方法。

@dynamic关键字

@property	NSStrinng	*firstNmae;
@property NSStrinng *firstNmae; @dynamic firstName, lastname; //编译器不会自动为这两个属性合成存取方法,或实例变量。

属性的特性

存取类型

  • readwrite (默认)编译器自动创建存方法和取方法
  • readonly 不生成存方法,如果一个属性不允许修改则可以将其声明为存方法。

在为以上类添加一个只读的ID和weight属性。

@property   (readonly)  NSInteger   ID;
@property (readwrite) NSInteger height;

如果我们这程序中试图修改person 的ID属性编译器就会报错

生命周期类型(内存管理类型)

生命周期类型的特性包括, assign, strong, weak和copy 这些特性决定了存方法如何处理与其相关的内存管理问题

  • assign (默认)最简单的,存入的值会将传入的值直接赋给实例变量。
@property	(assign)	NSInteger	ID;
这段代码等同于实现了一下存方法
- (void)setID:(NSInteger)d {
ID = d;
}
  • strong 特性要求保留传入的对象,并放弃原有对象(如果原有对象不在有其他拥有方,就会被释放)。凡是指向对象的实例变量,通常都应该使用strong
  • weak 要求不保留传入的对象,相应的存取方法会将传入的对象直接赋给实例变量。如果该对象被释放,那么相应的实例变量会呗自动置nil
  • copy 特性要求拷贝传入对象,并将新对象赋给实例变量。

copy 详解

看了很多博客讲解的copy都只是简单的说了一下,copy特性要求拷贝传入对象。并没有进行深入的讲解,比如为什么要copy传入对象,下面我写一下我自己对copy的理解

  1. 在OC中有些类会有特定的可修改的子类,比如 像NSString 和 NSMutableString 这些类我们平常使用时一般都声明为copy。像下面我们定义一个NSString 属性,但是给其存方法传入 NSMutableString 是合法的,声明为 copy,就可以避免修改 原对象对实例变量的影响
@property 	(strong)	NSString		*firstName;
@property (copy) NSString *lastName;
NSMutableString *name = [[NSMutable alloc] initWithString:@"Li"];
[person setFirstNmae:name];
[person setLastName:name];//这样修改name 不会对实例变量产生影响。
//看以下程序的输出
NSMutableString *firstName = [NSMutableString stringWithString:@"Zhang"];
NSMutableString *lastName = [NSMutableString stringWithString:@"San"];
person.firstName = firstName;
person.lastName = lastName;
NSLog(@"修改前的 :%@%@", person.firstName, person.lastName);
[firstName appendString:@"fe"];
[lastName appendString:@"aefa"];
NSLog(@"修改后的 :%@%@", person.firstName, person.lastName);
NSLog(@"%@%@", firstName, lastName);

2.如果传入的对象是不可修改的,copy方法实际是在调用copyWithZone:一般我们自定义的对象如果要求copy,应该重写 copyWithZone:方法从而优化copy过程

- (id)copyWithZond {
return self;
}
  1. copy返回的值总是不可修改的,如果需要copy出可修改的对象,需要使用对应的mutableCopy方法

atomic 和nonatomic

  • 如果不声明默认是atomic,atomic属性的存方法并不会对多线程下的安全有太大帮助,所以一般用nonatomic,而且atomic会影响性能。(确保线程安全必定会有额外开销)

理解 Objective-c "属性"的更多相关文章

  1. 【JVM虚拟机】(7)---深入理解Class中-属性集合

    #[JVM虚拟机](7)---深入理解Class中-属性集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机](6)- ...

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

    你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303 本文主要解说runtime相关知识, ...

  3. yii2知识点理解(成员属性)

    yii2成员属性 成员变量类似于public $a; 成员属性类似于 public function a(){} 成员变量是就类的结构构成而言的概念,而属性是就类的功能逻辑而言的概念 成员属性应用: ...

  4. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  5. 理解CSS Clip属性及用法

    应用Clip属性实现的一个简单效果图: 样式写法: .my-element { position: absolute; clip: rect(10px  350px  170px  0); /* IE ...

  6. 深入理解Spring Boot属性配置文件

    我们在开发Spring Boot应用时,通常同一套程序会被应用和安装到几个不同的环境,比如:开发.测试.生产等.其中每个环境的数据库地址.服务器端口等等配置都会不同,如果在为不同环境打包时都要频繁修改 ...

  7. 理解 CALayer ContentsCenter 属性

    http://aaronzjp.cn/2016/12/01/iOS-CALayer/ 这个属性和android 的 .9 文件类似,定义了图片的拉伸范围:例子中明显是四个角不拉伸,对于需要做背景,co ...

  8. js知识梳理1:理解对象的属性特性

    1.数据属性 数据属性的4个特性: Configurable:①表示能否通过delete删除属性从而重新定义,②能否修改属性的特性,③能否把属性修改为访问器属性.对象直接量里默认值true. Enum ...

  9. iOS数据存储之属性列表理解

    iOS数据存储之属性列表理解 数据存储简介 数据存储,即数据持久化,是指以何种方式保存应用程序的数据. 我的理解是,开发了一款应用之后,应用在内存中运行时会产生很多数据,这些数据在程序运行时和程序一起 ...

  10. 【JVM虚拟机】(8)--深入理解Class中--方法、属性表集合

    #[JVM虚拟机](8)--深入理解Class中--方法.属性表集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机] ...

随机推荐

  1. 【Lua】Lua中ipair和pair的区别

    pairs会遍历table的所有键值对. 而ipairs就是固定地从key值1开始,下次key累加1进行遍历,如果key对应的value不存在,就停止遍历.顺便说下,记忆也很简单,带i的就是根据int ...

  2. MVC中 Remote的用法

    一.web.config加入  <appSettings>    <add key="ClientValidationEnabled" value="t ...

  3. 前端-页面性能调试:Hiper

    前端-页面性能调试:Hiper   我们写单页面应用,想看页面修改后性能变更其实挺繁琐的.有时想知道是「正优化」还是「负优化」只能靠手动刷新查看network.而Hiper很好解决了这一痛点(其实Hi ...

  4. Ecshop如何解决Deprecated: preg_replace()报错

    今天安装Ecshop后,运行出现各种问题,其中 Deprecated: preg_replace() 之类的报错最多,下面贴出解决方案: 错误原因: preg_replace() 函数中用到的修饰符 ...

  5. 导入maven多模块项目 出现的问题

    近日导入maven多模块项目 出现的问题以及解决过程2017年12月04日 20:43:04 守望dfdfdf 阅读数:815 标签: jdkmavenmaven pom.xml 更多个人分类: 工作 ...

  6. PHP代码规范的一些总结

    世界第一语言在手,辅以前人的最佳实践,天下又算什么. 1.代码是写给小白用的 注释,注释,注释,重要的事情说三遍.我们做的虽然不是拿去卖源码的商业产品,不需要把注释写的多么优美.但也不要太过吝啬,到头 ...

  7. (转载)office 2003 gaozhi.msi 缺失提示问题修复

    某些GHOST版win7,自带office 2003,每次启动word,它都会提示"稿纸没安装"云云,找不到那个文件.可是我搜遍了硬盘,确实没有那个文件.每次都要点取消,这个提示才 ...

  8. JavaWeb中五种转发方式(转)

    今天本来是想找一下在jsp中实现转发的方式的,无意中看到了一篇文章,然后稍微综合了把服务器端的转发也包括在内.   1. RequestDispatcher.forward() 是在服务器端起作用,当 ...

  9. WPS去掉英语单词下面的红斜线

    我们在使用WPS的时候,经常会用到英语但是,但是在编码的时候,有些单词是缩写形成的,WPS就会自动验证,产生红色波浪线,提示我们单词写错的问题,那看起来就显得很不美观别扭 那么我们不想要这个红斜杠,怎 ...

  10. Netweaver和CloudFoundry里的trace开关

    Netweaver 事务码SU01的参数设置里,有很多关于trace(跟踪)的开关. FPTRACELEVEL: 设成04后,能将ADS生成PDF的trace信息写入生成的PDF. 详细原理参考我的b ...