IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS - 属性关键字 -> 正文阅读

[移动开发]iOS - 属性关键字

属性

属性:是OC的一项特性,用于封装对象中的数据。

  • iOS中通常用@property的形式来声明属性,一般为我们认为属性 = setter+ getter + 实例变量
  • 其实@property是一种语法糖,编译器会自动为你的实例变量生成setter和getter方法。你在获取这个属性值(NSLog(@"%@",self.name);)和设置属性值(self.name = @“dasheng”)的时候其实是调用了getter和setter方法获取和设置实例值。编译器帮你生成的实例变量就是你的属性名前面加个下划线。

补充:get和set方法的调用

  • 一般的调用方法,是传统的带中括号[ ]的调用方法
//比如上面的声明是一个Person类
Person* person=[[Person alloc]init];
[person setAge:13];
int age=[person age];
  • 点语法的方式
//点调用
person.age=13;  //.调用出现在=号左边,相当于setter
int age=person.age   //.调用出现在=号的右边,相当于getter
NSLog(@"%i",person.age);//这也是getter

关于get和set的注意点

  1. 属性的setter方法和getter方法是不能同时进行重写的

setter方法和getter方法不能同时进行重写

  1. 在getter方法中最后返回return _age;而不是return self.age, 这是因为点语法实际上是对setter和getter方法的调用,如果在getter方法中调用return self.age的话,就会循环调用。

  2. 声明set方法和get方法的规范

    a. set方法

    • 返回值类型必须是(void)。
    • 方法名以set开头,set后面跟上成员变量名(去掉下划线)且成员变量名首字母大写。
    • 形参名不能和成员变量名相同
    • 接收一个参数,参数的类型与成员变量类型一致。

    b. get方法

    • 返回值类型与成员变量类型一致。
    • 方法名与成员变量名(去掉下划线)相同。
    • 不需要接收参数

set和get方法

属性关键字和所有权修饰符不一样
在这里插入图片描述

@property/@synthesize/@dynamic语法

  • @property

    刚刚我们有讲iOS中通过@property来自动生成setter和getter方法以及实例变量,其实准确来讲,这种说法是不对的,实际上@property只会生成setter,getter的方法声明

  • @synthesize:

    @synthesize会在编译期创造一个指定的成员变量,并且生成属性的setter和getter方法的实现部分

    所以在之前是@property和@synthesize搭配使用,,后来编译器可以属性自动合成,所以现在我们的代码中已经很少看到@synthesize了

    然而@synthesize还有另外一个用法,我们也可以使用@synthesize来指定属性对应的实例变量名

    @synthesize name = realname;
    //前述语法会将生成的实例变量命名为realname,而不再使用默认的名字name,一般情况下无需修改默认的实例变量名。
    
  • @dynamic:

    它会告诉编译器,不要自动创建实现属性所用的实例变量,也不要为器创建存取方法,这就需要开发者自己来添加属性的实例变量名,动态合成实现getter和setter方法

属性关键字

属性关键字可以分为三种类型:

  1. 读写权限的类型: readonly ,readwrite
  2. 原子类 : atomic ,nonatomic
  3. 引用计数 : retain/strong/copy,assign/unsafe_unretained,weak

系统一般默认的关键字

  • 基本数据:atomic,readweite,assign
  • OC对象:atomic, readwrite,strong

属性关键字之原子类

  1. atomic:默认情况下,由编译器所合成的方法会通过锁定机制确保其原子(atomic)
  2. nonatomic: 如果属性具备nonatomic特质,则不使用同步锁。
  3. 一般都写nonatomic
  • 有效的属性值。若是不加锁的话(即nonatomic),那么其中一个线程正在改写某属性时,另一个线程突然闯入,就有可能读到不准确的数值。
  • 如果开发过iOS程序,你就会发现,所有的属性都声明为 nonatomic。这样做的历史原因是:在iOS程序中使用同步锁的开销较大,这会带来性能问题。一般情况下并不要求属性必须是“原子的”,因为这并不能保证“线程安全”,若要实现“线程安全”的操作,还需采用更为深层的锁定机制才行。例如:一个线程在连续多次读取某属性值的过程中有别的线程在改写该值,那么即便属性声明为atomic,也还是会读到不同的属性值。atomic仅保证了属性的setter/getter的线程安全,并不能保证使用属性的过程是线程安全的。因此,开发iOS程序时一般都会使用nonatomic属性。但是在开发MacOS X程序时,使用atomic属性通常时没有问题的。

属性关键字之读写权限

  • readwrite:拥有“获取方法”(getter)和“设置方法”(setter)readwrite是默认属性
  • readonly:仅拥有“获取方法”(getter)可以直接访问

属性关键字之引用计数

  1. strong
  • 先保留新值,再释放旧值,然后再将新值设置上去。

    在ARC下使用strong不用担心引用计数的问题,会在你不需要该对象时自动将其释放

  • 我持有这个对象,在我使用完它之前,不能销毁。

  • strong可以说是ARC下retain的表现形式

  1. retain
  • 释放旧对象,并使传入的新对象引用计数+1.
  • retain只能修饰oc对象,不能修饰非oc对象,一般用来修饰非NSString 的NSObject类和其子类。
  • retain在ARC环境下使用较少,在MRC下使用效果与strong一致
  1. assign
  • 修饰对象类型时,不改变引用计数

  • 修饰基本数据类型:int、bool ,NSInteger

  • 不能用assign去修饰对象,可以用来修饰基本数据结构

    对象的内存一般被分配到堆上,基本数据类型和oc数据类型一本被分配在栈上。

    如果用assign修饰对象,当对象释放后(因为不存在强引用,离开作用域对象内存可能被回收),指针的地址还是存在的,也就是说指针并没有被置为nil,下次再访问该对象就会造成野指针异常。对象是分配在堆上的,堆上的内存由程序员手动释放。

    用assign修饰基本数据类型或OC数据类型时,因为基本数据类型是分配在栈上的,由系统分配和释放,所以不会造成野指针。

  1. week
  • 不改变被修饰对象的引用计数。
  • 弱引用,指向赋值的对象,所指向的对象被释放之后会自动置为nil
  • 只要对象不在被强引用,那么该对象将会被释放,同时所有的弱指针都将被置为nil。可以避免循环引用。
  • 为这种属性设置新值时既不会保留新值也不会释放旧值,类似与assign
  1. copy
  • 在iOS开发中,一般copy关键字用在NSString、NSArray、NSDictionary等属性字段的修饰符。

  • 假如有一个NSMutableString,现在用他给一个retain(strong)修饰 NSString赋值,那么只是将NSString指向了NSMutableString所指向的位置,并对NSMutbaleString计数器加一,此时,如果对NSMutableString进行修改,也会导致NSString的值修改,原则上这是不允许的. 如果是copy修饰的NSString对象,在用NSMutableString给他赋值时,会进行深拷贝,及把内容也给拷贝了一份,两者指向不同的位置,即使改变了NSMutableString的值,NSString的值也不会改变.

    为了安全,防止NSMutbaleString赋值给NSString时,前者修改引起后者值的变化。

深浅复制

  • 深复制是内容复制,产生新对象,会产生新的内存空间
  • 浅复制是指针复制,没有产生新对象,会增加引用计数

copy关键字:

  1. copy修饰不可变对象、原对象为不可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是浅复制,两个指针指向的是同一个地址。
  2. copy修饰不可变对象,原对象为可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是深复制,两个对象指向的不同的地址,属性所指的是可变对象的副本,原对象如果被修改的话,不会影响属性的值,这时对属性进行增删改的操作,就会因为找不到方法而报错。
@property (nonatomic, copy) NSString *strCopy;

NSString *str = @"12345";

        person.strCopy = str;
        NSLog(@"%p %p", str, person.strCopy);

        NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"asdgfg"];
        person.strCopy = mutableString;
        NSLog(@"%p %p", mutableString, person.strCopy);

        [mutableString appendString:@"weret"];
        NSLog(@"mutableString - %@ %p, person.strCopy - %@ %p", mutableString, mutableString, person.strCopy, person.strCopy);

2021-07-30 21:51:15.015812+0800 属性关键字[59912:2479739] 0x100002060 0x100002060
2021-07-30 21:51:15.021123+0800 属性关键字[59912:2479739] 0x100620690 0x1f30fa489daca0dd
2021-07-30 21:51:15.049619+0800 属性关键字[59912:2479739] mutableString - asdgfgweret 0x100620690, person.strCopy - asdgfg 0x1f30fa489daca0dd

strong关键字

由于strong修饰属性在设置新值时,在setter方法中保留新值、并释放旧值,将新值设置上去,此时与原对象指向的是同一地址。
当原对象为可变对象时,将原对象赋给strong修饰的不可变对象,修改原对象,那我们不可变的对象也会随之改变

@property (nonatomic, strong) NSString *strCopy;

		NSString *str = @"12345";

        person.strCopy = str;
        NSLog(@"%p %p", str, person.strCopy);

        NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"asdgfg"];
        person.strCopy = mutableString;
        NSLog(@"%p %p", mutableString, person.strCopy);

        [mutableString appendString:@"weret"];
        NSLog(@"mutableString - %@ %p, person.strCopy - %@ %p", mutableString, mutableString, person.strCopy, person.strCopy);

//结果
0x100001060 0x100001060
0x10072baf0 0x10072baf0
mutableString - asdgfgweret 0x10072baf0, person.strCopy - asdgfgweret 0x10072baf0
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-01 14:37:31  更:2021-08-01 14:39:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 23:35:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码