ios 知识

IOS 类文件.h和.m中@interface的区别
大家都知道我们在创建类文件时会发现:

#import <UIKit/UIKit.h>@interface ViewController : UIViewController@end

#import "ViewController.h"@interface ViewController ()@end

那么他们之间有何区别呢?

1、.h里的@interface,是典型的头文件,它的属性(@property)和方法(functions)都是能够向其他类公开的。我们都知道有三种权限@private,@protected,@public。写在.h里的默认是@protected权限。

2、.m里的@interface,我们也可以称之为扩展(class extension),是.h文件中@interface的补充。可以增加属性,方法和成员变量,但是只能在.m文件里可见,对外是不开放的。在.m里的默认是@private权限

@END.

@property的作用和atomic和nonatomic

参考
当我们写下@property NSObject *foo时,编译器帮我们做了以下几件事:

创建实例变量_foo
声明foo属性的setter、getter方法
实现foo属性的setter、getter方法
@property 的本质是什么?

@property = ivar + getter + setter;实例变量+get方法+set方法,也就是说使用@property 系统会自动生成setter和getter方法;

@property的属性关键字详解
atomic和nonatomic
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。

atomic:系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。getter 还是能得到一个完好无损的对象(可以保证数据的完整性),但这个对象在多线程的情况下是不能确定的。

举个🌰
如果线程 A 调了 getter,与此同时线程 B 、线程 C 都调了 setter——那最后线程 A get 到的值,有3种 可能:可能是 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性 的值,可能是 B set 的值,也有可能是 C set 的值。所以atomic可并不能保证对象的线程安全。

也就是说:如果有多个线程同时调用setter的话,不会出现某一个线程执行完setter全部语句之前,另一个线程开始执行setter情况,相当于函数头尾加了锁一样,每次只能有一个线程调用对象的setter方法,所以可以保证数据的完整性。

atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的。

nonatomic:就没有这个保证了,nonatomic返回你的对象可能就不是完整的value。因此,在多线程的环境下原子操作是非常必要的,否则有可能会引起错误的结果。但仅仅使用atomic并不会使得对象线程安全,我们还要为对象线程添加lock来确保线程的安全。

nonatomic的速度要比atomic的快。atomic是Objc使用的一种线程保护技术,这种机制是耗费系统资源的,所以在iPhone这种小型设备上,我们基本上都是使用nonatomic,而对象的线程安全问题则由程序员代码控制。

atomic与nonatomic的本质区别其实也就是在setter方法上的操作不同

nonatomic对象、atomic对象setter和getter方法的实现:

/// nonatomic对象
- (void)setCurrentImage:(UIImage *)currentImage
{if (_currentImage != currentImage) {[_currentImage release];_currentImage = [currentImage retain];}
}
- (UIImage *)currentImage
{return _currentImage;
}/// atomic对象
- (void)setCurrentImage:(UIImage *)currentImage
{@synchronized(self) {if (_currentImage != currentImage) {[_currentImage release];_currentImage = [currentImage retain];}}
}- (UIImage *)currentImage
{@synchronized(self) {return _currentImage;}
}

总结:可以发现几乎所有代码的属性设置都会使用nonatomic,这样能够提高访问性能,在iOS中使用锁机制的开销较大,会损耗性能。

assign

1.这个修饰词是直接赋值的意思 , 整型/浮点型等数据类型都用这个词修饰 .
2.如果没有使用 weak strong retain copy 修饰 , 那么默认就是使用 assign 了.
3.当然其实对象也可以用 assign 修饰 , 只是对象的计数器不会+1 . ( 与 strong 的区别 )
4.如果用来修饰对象属性 , 那么当对象被销毁后指针是不会指向 nil 的 . 所以会出现野指针错误 . ( 与weak的区别 )

weak

weak是弱引用,用weak描述修饰或者所引用对象的计数器不会加一,并且会在引用的对象被释放的时候自动被设置为nil,大大避免了野指针访问坏内存引起崩溃的情况,另外weak还可以用于解决循环引用。

weak原理概括
weak表其实是一个hash(哈希)表,Key是所指对象的地址,Value是weak指针的地址数组。weak的底层实现的原理是什么?

Runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。weak表其实是一个hash表,Key是所指对象的地址,value是weak指针的地址(这个地址的值是所指对象指针的地址)数组。

为什么value是数组?因为一个对象可能被多个弱引用指针指向

strong

在ARC环境下,只要某一对象被一个strong指针指向,该对象就不会被销毁。如果对象没有被任何strong指针指向,那么就会被销毁。在默认情况下,所有的实例变量和局部变量都是strong类型的。可以说strong类型的指针在行为上跟非ARC下的retain是比较相似的

copy

浅拷贝

只是将对象内存地址多了一个引用,也就是说,拷贝结束之后,两个对象的值不仅相同,而且对象所指的内存地址都是一样的。
深拷贝

拷贝一个对象的具体内容,拷贝结束之后,两个对象的值虽然是相同的,但是指向的内存地址是不同的。两个对象之间也互不影响,互不干扰。

@interface 和 @implementation

在这里插入图片描述
OC中的类必须包括两部分,interface部分和implementation部分,这才是oc中的一个类的完整声明;
OC中将成员变量和成员方法的声明部分放置在interface部分中,包括继承关系,protocal实现关系,都在interface里面的头部进行声明,
然后将实现部分放置在implementation部分中,相当于是将类拆分成声明和实现两部分,这两部分缺一不可,所以在OC中,不妨不要将interface叫做接口,直接叫做类声明部分来得容易理解多了,简而言之,oc中interface是类的一个部分,和implementation共同组成一个完整的类。

- (instancetype)init

这个就是该类的初始化
参考

 (instancetype)init{self=[super init];if (self) {}NSLog(@"=========in MyView.init 函数里");return  self;
}

+和-

+号是static
在这里插入图片描述

self 和 super

self指的是类对象本身;
super是父类对象本身;
self用来调用本类对象的方法;
self关键字先从本类中查找是否有此方法,如果没有,再从父类中调用此方法;
super调用从父类继承下来的方法;
super关键字直接调用父类中定义的方法.

//方法定义

(void)shopping;//不带参数的方法
-(void)goshopping:(float)price; //带参数的方法
-(id)someMethod:(int)someArg someOtherArgName:(int)someOtherArg; //otherParameter是参数的别名(第一个参数的别名省略),在函数调用时方便指定。

new、alloc

Object-C中的方法调用形式采用消息发送的方式,通常调用的形式如:

[someObject someMethod:firstArg someOtherArgName:otherArg];

实例的初始化也采用消息发送的形式,可以简单的调用类型的new方法来获取一个实例对象,简单实例化的方法通常是:

someObject *obj = [someObject new]; //类的实例化

new 方法的实际过程是调用 alloc 和 init 方法,因此如果需要采用自定义的方法来初始化实例,则需要自己重写 init 方法,通常的初始化方式为:

someObject *obj = [[someObject alloc] init]; //采用无参数的init实例化   
someObject *obj = [[someObject alloc] initWithArg:Arg]; //采用参数的实例化 

调用方法

在这里插入图片描述
方法调用的本质就是放对象发送消息

/* new 会调用 init方法 */
People *man = [People new];//类调用new
People *man = [[People alloc] init];//类创建了个对象,调用init//属性方法调用eat的方式
[man eat];
//类方法调用eat方式
[People eat];
[[People class] eat];//还有一种不常用的调用方式
[对象/类 performSelector:@selector(eat)];//底层实现
objc_msgSend(对象/属性, @selector(eat));

//_render对象调用registerModule方法,参数是_lookupDescriptor

[_render registerModule:_lookupDescriptor];

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

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

相关文章

MySql存储过程详解

文章目录 存储过程1 介绍 基本语法创建:调用查看删除演示: 变量相关系统变量演示: 用户自定义变量局部变量 if语法参数介绍casewhilerepeatloop游标条件处理程序存储函数 存储过程 1 介绍 存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合&#xff0c;调用存储过…

kafka 02——三个重要的kafka客户端

kafka 02——三个重要的kafka客户端 1. 前言1.1 关于 Kafka 的安装1.2 常用客户端简介1.3 依赖 2. AdminClient2.1 Admin Configs2.2 AdminClient API2.2.1 设置 AdminClient 对象2.2.2 创建 topic 获取 topic 列表2.2.3 删除topic2.2.4 查看 topic 的描述信息2.2.5 查看 topi…

Python系统学习1-7-字典

一、字典 1、概念及内存图 列表&#xff1a;由一系列变量组成的可变序列容器字典&#xff1a;由一系列键值对组成的可变散列容器字典优势&#xff1a;利用&#xff08;内存&#xff09;空间&#xff0c;换取&#xff08;CPU查找&#xff09;时间 键key 必须唯一且为不…

学无止境·运维高阶⑤(LVS-DR 群集 配置Nginx负载均衡)

LVS-DR 群集 && 配置Nginx负载均衡 一、LVS-DR 群集1、相关配置环境2、在RS上配置并启动脚本2.1相关脚本2.2 启动脚本&#xff0c;另一台RS同样步骤 3、LVS-DR模式配置脚本4、测试 二、Nginx负载均衡1、安装Nginx并关闭相应设置2、向主机 node2&#xff0c;node3 写入内…

JDK 17 营销初体验 —— 亚毫秒停顿 ZGC 落地实践 | 京东云技术团队

前言 自 2014 年发布以来&#xff0c; JDK 8 一直都是相当热门的 JDK 版本。其原因就是对底层数据结构、JVM 性能以及开发体验做了重大升级&#xff0c;得到了开发人员的认可。但距离 JDK 8 发布已经过去了 9 年&#xff0c;那么这 9 年的时间&#xff0c;JDK 做了哪些升级&am…

《golang设计模式》第二部分·结构型模式-01-适配器模式(Adapter)

文章目录 1. 概念1.1 角色1.2 应用场景1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 示例类图 1. 概念 定义一个适配器&#xff0c;帮助原本不能实现接口的类“实现”该接口 1.1 角色 目标&#xff08;Target&#xff09;&#xff1a;客户端调用的目标接口 被适配者&#xff08…

OSI七层模型及TCP/IP四层模型

目录 OSI七层模型 TCP/IP四层模型 OIS七层模型和TCP/IP模型图 七层详解 两种模型比较 为什么OSI七层体系结构不常用 四层详解 网络为什么要分层&#xff1f; 说说 OSI 七层模型和 TCP/IP 四层模型的关系和区别 OSI七层模型 OSI&#xff08;Open System Interconnect&a…

ModaHub魔搭社区:Milvus Cloud素材集合帖,等你查收

Hi~Milvus Cloud 的各位朋友,这是一期 Milvus Cloud 素材弹药库的集中汇总帖。随着向量数据库的火爆,越来越多的伙伴开始关注到向量数据库并开始使用 Milvus Cloud 。 考虑到目前信息获取的渠道多且分散,我们专门为大家整理了一期 Milvus Cloud 信息集合帖,让大家可以在快…

ppt怎么压缩?试试这样压缩文件

当PPT文件体积过大时&#xff0c;打开的速度就会很慢&#xff0c;演示的时候刘程度也会受到影响&#xff0c;其次&#xff0c;现在很多平台对于上传的文件是有大小限制的&#xff0c;比如超过100M的文件就无法上传、发送等等&#xff0c;那么&#xff0c;怎么才能压缩PPT文件呢…

CentOS安装Postgresql

PG基本安装步骤 安装postgresql&#xff1a; sudo yum install postgresql-server初始化数据库&#xff1a;安装完毕后&#xff0c;需要初始化数据库并创建初始用户&#xff1a; sudo postgresql-setup initdb启动和停止服务&#xff1a; sudo systemctl start postgresql sudo…

Android之版本号、版本别名、API等级对应关系(全)(一百六十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

微服务07-分布式缓存

前提: 单机的Redis存在四大问题: 解决办法:基于Redis集群解决单机Redis存在的问题 1、Redis持久化 Redis 具有持久化功能,其会按照设置以 快照 或 操作日志 的形式将数据持久化到磁盘。 Redis有两种持久化方案: RDB持久化AOF持久化注意: RDB 是默认持久化方式,但 Red…

Clone函数

概述 Clone函数是一种用于复制的计算机函数。在程序编写中&#xff0c;除了自定义一个拷贝构造函数来实现对象复制外&#xff0c;还可以实现一个clone函数。这需要借助编译器实现的一个隐藏拷贝构造函数&#xff0c;这样的做法&#xff0c;更省心。 中文名clone函数外文名clon…

Sql server还原失败(数据库正在使用,无法获得对数据库的独占访问权)

一.Sql server还原失败(数据库正在使用,无法获得对数据库的独占访问权) 本次测试使用数据库实例SqlServer2008r2版 错误详细&#xff1a; 标题: Microsoft SQL Server Management Studio ------------------------------ 还原数据库“Mvc_HNHZ”时失败。 (Microsoft.SqlServer.…

设计模式之Bridge模式的C++实现

目录 1、Bridge模式的提出 2、Bridge模式的定义 3、Bridge模式总结 4、需求描述 5、多继承方式实现 6、使用Bridge设计模式实现 1、Bridge模式的提出 在软件功能模块设计中&#xff0c;如果类的实现功能划分不清晰&#xff0c;使得继承得到的子类往往是随着需求的变化&am…

关于 Eclipse 的一场 “三角关系”

上个世纪 90 年代&#xff0c;世界上的计算机要么不联网&#xff0c;要么在企业内部联网。但是&#xff0c;在互联网的概念下&#xff0c;计算机之间共享信息和资源的需求成为了必要。 1995 年 5 月&#xff0c;Java 横空出世。Java 的父亲是当时凭借 Solaris 操作系统风头正盛…

flutter 手写日历组件

先看效果 直接上代码 calendar_popup_view.dart import package:flutter/material.dart; import package:intl/intl.dart;import custom_calendar.dart; import hotel_app_theme.dart;class CalendarPopupView extends StatefulWidget {const CalendarPopupView({required th…

OpenCV项目开发实战--相机校准—并附实例Python/C++代码实现

介绍 相机标定是计算机视觉中的一项基本任务在 3D 重建、对象跟踪、增强现实和图像分析等各种应用中至关重要。准确的校准通过校正失真和估计相机的内在和外在参数来确保精确的测量和可靠的分析。这本综合指南深入探讨了相机校准的原理、技术和算法。我们探索获取相机的内在和…

macOS使用ffmpeg与QT进行音视频推拉流

1.先启动流服务器 ./mediamtx 2.开始推流: ffmpeg -re -stream_loop -1 -i /Users/hackerx/Desktop/test.mp4 -c copy -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream 3. 安装ffmpeg 4.4 brew install ffmpeg4 4.添加ffmpeg头文件目录与库目录 5.链接ffmpeg相关库…

Flink窗口分类简介及示例代码

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 1. 流式计算2. 窗口3. 窗口的分类◆ 基于时间的窗口&#xff08;时间驱动&#xff09;1) 滚动窗口&#xff08;Tumbling Windows&#xff09;2) 滑动窗口&#xff08;Sliding Windows&…