理解 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. web小trick

    1.linux下交换文件 .index.php.swp 有时可查看源码2.当php后缀被过滤的时候可以直接对ph开头的后缀进行一个fuzz测试可以上传的文件后缀名3.curl -x 123.45.67 ...

  2. java中调用ElasticSearch中文分词ik没有起作用

    问题描述: 项目中已经将'齐鲁壹点'加入到扩展词中,但是使用客户端调用的时候,高亮显示还是按照单个文字分词的: 解决方案: 1.创建Mapping使用的分词使用ik 2.查询使用QueryBuilde ...

  3. aspx有"记住我"的登录

    客户端 <form id="form1" runat="server"> <div> 用户名:<input type=" ...

  4. sublime 常用快捷键(转)

    Sublime text 3是码农最喜欢的代码编辑器,每天和代码打交道,必先利其器,掌握基本的代码编辑器的快捷键,能让你打码更有效率.刚开始可能有些生疏,只要花一两个星期坚持使用并熟悉这些常用的快捷键 ...

  5. jQuery遍历Table表格的行和列

    遍历Table表格的行和列,在开发中比较常用的功能,特别是前端开发人员,不多说,直接上代码,下面代码只是弹出第一列字段,请各位自己根据需求修改和扩展! <!DOCTYPE html PUBLIC ...

  6. HttpURLConnection(http 1.1) 用法、状态码、状态描述

    最近研究了java的HttpURLConnection的用法, 这里简单的做一下记录: Java中可以使用HttpURLConnection来请求WEB资源. 1. URL请求的类别 分为二类,GET ...

  7. uvm_analysis_port——TLM1事务级建模方法(二)

    UVM中的TLM1端口,第一类是用于uvm_driver 和uvm_sequencer连接端口,第二类是用于其他component之间连接的端口,如uvm_monitor和uvm_scoreboard ...

  8. html代码能让网页的横向滚动条默认居中

    在body 中加入 onload="window.scrollTo((document.body.scrollWidth-document.body.offsetWidth)/2,0)&qu ...

  9. java Vamei快速教程05 实施接口

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在封装与接口中,private关键字封装了对象的内部成员.经过封装,产品隐藏了内部 ...

  10. 初学树套树:线段树套Treap

    前言 树套树是一个十分神奇的算法,种类也有很多:像什么树状数组套主席树.树状数组套值域线段树.\(zkw\)线段树套\(vector\)等等. 不过,像我这么弱,当然只会最经典的 线段树套\(Trea ...