热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Objectivec:属性

简介属性(property)是Objective-C的一项特性,用于封装对象中的数据。Objective-C对象通常会把其所需要的数据保存

简介
属性(property)是Objective-C的一项特性,用于封装对象中的数据。Objective-C对象通常会把其所需要的数据保存为各种实例变量。实例变量一般通过“存取方法”(access method)来访问。其中,“获取方法”(getter)用于读取变量值,而“设置方法”(setter)用于写入变量值。这个概念已经定型,并且经由“属性”这一特性而成为Objective-C 2.0 的一部分,开发者可以令编译器自动编写与属性相关的存取方法。此特性引入了一种新的“点语法”(dot syntax),使开发者可以更为容易地依照类对象来访问存放于其中的数据。
属性声明
语法格式:@property (参数1, 参数2...) 类型 名字;
#import

@interface Person : NSObject

// 属性生命
// 关键字   参数1     参数2      类型      名字
@property (strong, nonatomic) NSString *name;

@end

Tips

1、属性声明中的参数,将会在后文详细讲解;

属性的声明,需声明在@interface和@end之间,全局变量的下方,与方法的声明类似。

在 iOS4.4 之前,我们需要用到另一个属性关键字@synthesize,他的意义在于,将一个属性与对应的全局变量合成,这个关键字在iOS4.4以后不必再写出,系统会自动添加,但是实例变量依旧可用;

@synthesize name = _name;

在 iOS4.4 以后,使用前面的方法声明了一个属性即可直接使用,但是我们依然需要了解一个属性的完整诞生过程,它能帮我们更好的使用属性;

声明一个属性本质上就是指定一个set和取值方法,所以像前面提到的那些set和取值,都不写出,但是方法依旧可用。

iOS5之前和iOS5之后,属性在定义形式上做了一定的简化,不重写setter()和getter()方法时,也可不使用@synthesize 关键字,且成员变量不必写出,也能自动生成一个带下划线的同名成员变量;

iOS5之前,书写属性的步骤:

1) 先写出带下划线的成员变量;如 NSString * _name;

2) 使用@property 配备一个不带下划线,且与成员变量同名的属性;

@property(nonatomic , retain) NSString * name;

3)使用关键字@synthesize将成员变量和属性名进行合成;

@synthesize name = _name;

属性关键字
@property后面的()内可以配置一些参数,配置了参数后,编译器会为我们生成不同的getter和setter方法,下面我们来看看有哪些可配置的参数:

读写属性
读写属性即控制了属性是否存在设置器方法,这些参数之间是互斥的。

readwrite(默认): 表名了属性是可读可写的,即属性具有setter方法和getter方法,若该属性由@synthesize实现,则编译器会自动生成这两个方法;

readonly:表明属性是只读的,即属性只有获取器方法,将生成getter方法而不生成setter方法。如果视图对该属性使用点语法赋值,将引起编译器错误,只有当该属性由@synthesize实现时,编译器才会为其合成获取方法;

原子性
automic(默认):这个属性是为了保证程序在多线程情况,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题;

nonatomic:该属性不提供多线程保护,如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率;

内存管理语义
属性用于封装数据,而数据则要有“具体的所有权语义”。下面这一组特质仅会影响“设置方法”。例如,用“设置方法”设定一个新值时,它应该是“保留(retain)”此值呢,还是只将其赋给底层实例变量就好?编译器在合成存取方法时,要根据此特质来决定所生成的代码。如果自己编写存取方法,那么久必须同有相关属性所具备的特质相符。

retain:对象使用,持有对象,retainCount + 1;

assion:这个属性一般用来处理基础类型,比如int、float等待,如果你声明的属性是基础类型的话,assign是默认的,你可以不加这个属性;

strong:此特质表明该属性定义了一种“拥有关系”。为这种属性设置新值时,设置方法会先保留新值,释放旧值,然后再将新值设置上去。主要用于修饰强引用的属性;

weak:此特质表明该属性定义了一种“非拥有关系”。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assin类似,然而在属性所指的对象遭到摧毁时,属性值也会清空。主要用于修饰弱引用的属性,当弱引用的对象被释放后,该对象将被自动赋予nil值;

copy:此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝”。当属性类型为NSString*时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。这个类是NSString的子类,表示一种可以修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变”的字符串,确保对象中的字符串值不会无意间变动,只要实现属性所用的对象是“可变的”,就应该在设置新属性时拷贝一份。我们可以暂时这样理解,当它使用在不可变类型的属性时,等于strong;当它使用在可变类型时,每次赋值都会拷贝一个新的对象。

unsafe_unretained:此特质语义和assin相同,但是它适合用于“对象类型”,该特质表达一种“非拥有关系”,当目标对象遭到摧毁时,属性值不会自动清空(置为nil),这一点与weak有区别。

方法名
可通过如下特质来制定存取方法的方法名:

getter=:指定“获取方法”的方法名。如果某属性时Boolean型,而你想为其获取方法加上is前缀,那么就可以用这个方法来指定。比如说,在登陆界面,表示登陆状态的属性就是这样定义的:
@property (nonatomic, assign, getter=isLogin) BOOL login;
1
setter=:指定“设置方法”的方法名,这种用法不太常见,用法与getter=一致;
Tips

1、一般情况下,只要是对象类型,都使用strong(后面可能有例外);

2、只要是非对象类型,都使用assign;

3、ARC模式下

weak 相当于 assign 相当于,但不等价,注意;

strong 相当于 retain 相当于;

点语法
点语法简介
有了属性,我们就可以使用另外一个语法:点语法。使用方法如下:

person.name = @"Admin";       // 设置器方法

NSString *name = person.name; // 访问器方法

Tips

1、第一个左边部分相当于一个设置器方法;

2、第二个右边部分相当于一个访问器方法;

3、点语法是objective-C 2.0 的新特性。一般声明完属性之后才能使用点语法;

点语法有点
方便程序员能够很快地转到OC上来;

让程序设计简单化;

隐藏了内存管理细节;

隐藏了多线程、同步、加锁细节;

点语法缺点
性能有点差,内部转化为setter,getter;

不易理解苹果的调用机制;

补充
在dealloc方法中,我们可以采用一种高明的技巧;

self.name = nil;

// 这行代码表示使用nil参数调用setAge:方法。生成的访问器方法将自动释放以前的age对象,并使用nil值替代,这样可以使我们避免对已有释放内存的悬空引用问题。


推荐阅读
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
author-avatar
手机用户2602933971
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有