【iOS】属性关键字

目录

深浅拷贝

自定义类

容器类深拷贝

属性关键字

原子操作

atomic

nonatomic

读写权限

readwrite

readonly

内存管理

weak

assign

strong

retian

copy

strong与copy

补充

属性关键字格式

ARC下@property的默认属性


深浅拷贝

关于深浅拷贝,笔者在之前已经有博客进行过详细的阐述,下面附上深浅拷贝的链接

深浅拷贝

在这篇博客中,笔者讲述了深浅拷贝的基本概念和区别,也解释了一些有关于容器类深拷贝的知识,这里来做一些补充。

自定义类

自定义类无论是copy还是mutablecopy都为深拷贝,因为自定义类没有copyWithZone:和mutableCopyWithZone:两个方法,需要遵守NSCopying和NSMutableCopying协议自己实现这两个拷贝方法。

容器类深拷贝

容器类对象的深拷贝分为两种,一种是单层深拷贝,另一种是完全深拷贝。

  • 单层深拷贝:对于副本对象本身是深拷贝,但是容器中的所有对象都是浅拷贝
  • 完全深拷贝:对于副本对象本身与其里面的所有对象都是深拷贝

非可变容器类在mutablecopy时是单层深拷贝,可变容器类在使用copy和mutablecopy时都是单层深拷贝,那么要如何才能实现容器类的完全深拷贝呢?

先给出结论:当容器类对象中的对象是自定义对象或不为immutable对象,使用initWithArray:copyItems:方法(第二个参数设置为YES)可以实现完全深拷贝;当容器内对象是容器类时,使用initWithArray:copyItems:方法(第二个参数设置为YES)可以实现单层浅拷贝,这时就需要使用归档和解档来实现完全深拷贝

比如:dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]]

- (void)test {NSMutableArray* array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],[NSMutableString stringWithString:@"2"],[NSMutableString stringWithString:@"3"],[NSMutableString stringWithString:@"4"],nil];NSMutableArray* array2 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"one"],[NSMutableString stringWithString:@"two"],[NSMutableString stringWithString:@"three"],[NSMutableString stringWithString:@"four"],array1,nil];NSMutableArray* array3 = [array2 mutableCopy];//NSMutableArray* array4 = [[NSMutableArray alloc] initWithArray:array2 copyItems:YES];NSMutableString* mutableString;mutableString = array2[0];[mutableString appendString:@"--ONE"];NSLog(@"array3:%@", array3);NSLog(@"array2:%@", array2);
}

这段代码容器类对象使用mutablecopy,输出的结果是修改array2中的元素,array3也会发生改变,说明这是单层深拷贝,也就是说对于array2和array3是深拷贝,而对于数组中的元素却还是浅拷贝。

如果使用initWithArray:copyItems:方法呢?

- (void)test {NSMutableArray* array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],[NSMutableString stringWithString:@"2"],[NSMutableString stringWithString:@"3"],[NSMutableString stringWithString:@"4"],nil];NSMutableArray* array2 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"one"],[NSMutableString stringWithString:@"two"],[NSMutableString stringWithString:@"three"],[NSMutableString stringWithString:@"four"],array1,nil];NSMutableArray* array3 = [array2 mutableCopy];NSMutableArray* array4 = [[NSMutableArray alloc] initWithArray:array2 copyItems:YES];NSMutableString* mutableString;mutableString = array2[0];[mutableString appendString:@"--ONE"];NSLog(@"array3:%@", array3);NSLog(@"array2:%@", array2);NSLog(@"array4:%@", array4);
}

可以看出,array4实现了完全深拷贝。

那如果是针对于容器类里的容器类对象呢?

- (void)test {NSMutableArray* array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],[NSMutableString stringWithString:@"2"],[NSMutableString stringWithString:@"3"],[NSMutableString stringWithString:@"4"],nil];NSMutableArray* array2 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"one"],[NSMutableString stringWithString:@"two"],[NSMutableString stringWithString:@"three"],[NSMutableString stringWithString:@"four"],array1,nil];NSMutableArray* array3 = [array2 mutableCopy];NSMutableArray* array4 = [[NSMutableArray alloc] initWithArray:array2 copyItems:YES];NSMutableString* mutableString;mutableString = array2[0];[mutableString appendString:@"--ONE"];NSMutableString* mutableString1;NSMutableArray* mutableArray = array2[4];mutableString1 = mutableArray[0];[mutableString1 appendString:@"--ONE"];NSLog(@"array3:%@", array3);NSLog(@"array2:%@", array2);NSLog(@"array4:%@", array4);
}

 

 可以看出容器类中的容器类对象使用initWithArray:copyItems:只能实现单层的深拷贝。

属性关键字

@property

@synthesize

@dynamic

这三个关键字是有关于属性自动合成存取方法的关键字:

用 @property 语法来声明属性。@property 会帮我们自动生成属性的 setter 和 getter 方法的声明

@synthesize帮我们自动生成 setter 和 getter 方法的实现以及合成实例变量。

@dynamic告诉编译器不用自动进行 @synthesize,你会在运行时再提供这些方法的实现,无需产生警告

现在的版本已经不再需要@synthesize 编译器会自动合成存取方法。

下面是一些修饰属性的关键字

原子操作

原子操作:属性是否有原子性可以理解为线程是否安全

  • atomic

原子性,加同步锁,默认修饰符。 使用atomic会损耗性能,也不一定保证线程安全。如果保证线程安全需要使用其他锁机制。

非原子性,不实用同步锁。 声明属性时基本设置为nonatomic。使用nonatomic能够提高访问性能。

读写权限

读写权限不写时默认为 readwrite

属性拥有setter方法和getter方法

仅有getter方法

内存管理

weak

  1. ARC 下才能使用;
  2. 修饰弱引用,不增加对象引用计数,主要可以用于避免循环引用;
  3. weak 修饰的对象在被释放之后,会自动将指针置为 nil,不会产生悬垂指针;

assign

  1. 既可以修饰基本数据类型,也可以修饰对象类型;
  2. setter 方法的实现是直接赋值,一般用于基本数据类型 
  3. 修饰对象类型时,不增加其引用计数;
  4. 会产生悬垂指针(悬垂指针:assign 修饰的对象在被释放之后,指针仍然指向原对象地址,该指针变为悬垂指针。这时候如果继续通过该指针访问原对象的话,就可能导致程序崩溃)。

strong

  1. ARC 下才能使用;
  2. 原理同 retain;
  3. 但是在修饰 block 时,strong 相当于 copy,而 retain 相当于 assign。

retian

  1. MRC 下使用,ARC 下基本使用 strong;
  2. 修饰强引用,保留新值,释放旧值,再设置新值,同时将新对象的引用计数加 1;
  3. setter 方法的实现是 release 旧值,retain 新值,用于 OC 对象类型。

copy

setter 方法的实现是 release 旧值,copy 新值。用于 NSString、NSArray、NSDictionary 是为了保证赋值后是一个不可变对象,以免遭外部修改而导致不可预期的结果。

strong与copy

如果属性声明中指定了copy特性,合成方法会使用类的copy方法

相同点:用于修饰标识拥有关系的对象

不同点:strong的赋值是多个指针指向同一个地址,而copy的复制就是每次会在内存中复制一份对象,指针指向不同的地址。

strong与copy可以理解为深浅拷贝的区别

补充

属性关键字格式

推荐按照下面的格式来定义属性

@property (nonatomic, readwrite, copy) NSString *name;

属性的修饰符应该按照上面的顺序排列:原子操作、读写权限、内存管理

ARC下@property的默认属性

对于基本数据类型:atomic、readwrite、assign
对于普通的Objective-C对象:atomic、readwrite、strong

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/53249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ClickHouse的安装教程

ClickHouse的安装教程 文章目录 ClickHouse的安装教程写在前面准备工作关闭防火墙CentOS 取消打开文件数限制安装依赖CentOS 取消 SELINUX 单机安装在 **node01** 的/opt/software 下创建 clickhouse 目录将下载的文件上传到 node01 的 /opt/software/clickhouse 目录下将安装文…

FPGA第 9 篇,Verilog 中的关键字和基数

前言 在 Verilog 中,关键字(Keywords)和基数(Radix)是语言的重要组成部分,它们有助于描述和定义硬件设计。上期分享了 Verilog 的基本使用,以及数据类型、逻辑值和算数运算符的简单应用&#x…

快手电商上线 “金秋赶蟹季” 活动,特别推出“蟹无忧”服务

金秋九月,正是品蟹好时节。为引入更多源头好蟹,快手电商发起了「金秋赶蟹季」溯源活动。为了让全国老铁提前品尝肥美的盘锦河蟹,9月3日,快手电商携手盘山县人民政府举行盘锦河蟹开捕仪式,并在快手小店 直播间进行全程直…

SprinBoot+Vue校园活动报名微信小程序的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue3.6 uniapp代码 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平…

性能测试经典案例解析——政务查询系统

各位好,我是 道普云 一站式云测试SaaS平台。一个在软件测试道路上不断折腾十余年的萌新。 欢迎关注我的主页 道普云 文章内容具有一定门槛,建议先赞再收藏慢慢学习,有不懂的问题欢迎私聊我。 希望这篇文章对想提高软件测试水平的你有所帮…

docker拉取redis5.0.5并建立redis集群

1.配置文件 mkdir -p redis-cluster/7001/ mkdir -p redis-cluster/7002/ mkdir -p redis-cluster/7003/ mkdir -p redis-cluster/7004/ mkdir -p redis-cluster/7005/ mkdir -p redis-cluster/7006/cd redis-clustervim 7001/redis.confbind 0.0.0.0port 7001cluster-enabled…

IJCAI-信也科技杯全球AI大赛-华东师范大学亚军队伍分享

作者:彭欣怡(找不到工作版) 华东师范大学; 马千里(搬砖版) 虾皮; 指导:闫怡搏(科研版) 华东师范大学 比赛链接:https://ai.ppdai.com/mirror/goToMirrorDetailSix?mirrorId34 前言 这是我们首次参加语音领域的比赛,最初只是抱着…

C语言程序设计 笔记代码梳理 重制版

前言 第1章 C语言的流程 1.C程序经历的六个阶段 编辑(Edit)预处理(Preprocess)编译(Compile)汇编(Assemble)链接(Link)执行(Execute) 2.C语言编写代码到运行 都是先编译,后链接,最后运行。(.c ---> .obj --->.exe)这个过…

开发适合el-dialog的拉伸拖拽自定义指令和适配自定义的图片查看组件

目录 一、应用场景 二、开发流程 1.自定义指令 2.功能原理 3.难点 三、详细开发 四、总结 一、应用场景 我之前有开发过一个图片查看的组件,这个组件可在单页面打开,也可以在弹窗里打开,但是弹窗因为是比较固定,所以有一些…

常见限流算法-固定窗口、滑动窗口、漏桶、令牌桶

为什么需要限流 限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。比如:延迟处理,拒绝处理…

OpenCV颜色空间转换(1)颜色空间转换函数cvtColor()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将图像从一个颜色空间转换到另一个颜色空间。 此函数将输入图像从一个颜色空间转换到另一个颜色空间。在进行 RGB 颜色空间之间的转换时&#x…

怎样查看电脑文件夹大小?文件夹数据丢失怎么找回

在日常使用电脑的过程中,‌我们经常需要查看文件夹的大小,‌以便更好地管理磁盘空间。‌然而,‌有时我们可能会遇到文件夹数据丢失的问题,‌这可能是由于误删除、‌系统错误或病毒感染等多种原因造成的。‌本文旨在介绍如何查看电…

【苍穹外卖】Day 7 地址簿、下单、定时处理

1 地址簿模块 地址簿实体对象: package com.sky.entity;import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor;import java.io.Serializable;/*** 地址簿*/ Data Builder NoArgsConstructor AllArgsCon…

001集——CAD—C#二次开发入门——开发环境基本设置

CAD C#二次开发首先需要搭建一个舒服的开发环境,软件安装后,需要修改相关设置。本文为保姆级入门搭建开发环境教程,默认已成功安装vs和cad 。 第一步:创建类库 第二步:进行相关设置,如图: 下一…

JavaEE:多线程进阶(CAS)

文章目录 CAS什么是 CASCAS 伪代码 CAS有哪些应用CAS的ABA问题什么是ABA问题ABA问题带来的BUG解决方案 CAS 什么是 CAS CAS: 全称Compare and swap,字面意思:”比较并交换“,一个 CAS 涉及到以下操作: 我们假设内存中的原数据V,旧的预期值A…

刷题记录(2)

1. HWOD机试 - 模拟消息队列(100) package com.yue.test;import org.junit.Test;import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List;/*** Author: 夜雨* Date: 2021-12-08-10:31* Description:* Version 1.0*/ public…

【Android】ViewPager基本用法总结

文章目录 一、添加ViewPager控件二、构建适配器类三、在 MainActivity 中设置适配器示例一:图片切换适配器MainActivity 示例二:Fragment切换适配器FragmentMainActivity ViewPager 是 Android 中一个用于在同一屏幕上滑动不同页面(通常是左右…

OBS怎么设置录制配置?3个电脑录屏小技巧妥妥教会你

OBS Studio是一款广受好评的开源录屏和直播软件,它以其强大的功能和用户友好的操作界面而闻名。对于初次接触OBS的用户来说,可能会对软件的众多按钮感到困惑。本文将为你提供一份简洁明了的OBS录屏指南,帮助你快速上手。 演示机型&#xff1a…

Hive数据库与表操作全指南

目录 Hive数据库操作详解 创建数据库 1)语法 2)案例 查询数据库 1)展示所有数据库 (1)语法 (2)案例 2)查看数据库信息 (1)语法 (2&#…

Simulink:循环计数器 Counter Free-Running

原文:Matlab生成stm32代码_matlab stm32-CSDN博客 使用“Counter Free-Running”模块进行计数,参数配置如下 此配置的意思为每0.5秒计数一次,计数的最大值为2^Nbits – 1,其中Nbits为所填的2,所以这里最大值为3。 示波…