美文网首页
2020-11-23

2020-11-23

作者: 浩楠Bruce | 来源:发表于2020-11-23 17:24 被阅读0次

总结:

UIKit 框架
AppDelegate类实现了UIKit库中的UIApplicationDelegate 协议

post和get的区别
get : GET提交的数据放在URL中. URL长度一般有限制所以GET方法的参数长度不能太长. get 不安全,能被缓存. GET只允许ASCII字符.
post : GET回退浏览器无害,POST会再次提交请求(GET方法回退后浏览器再缓存中拿结果,POST每次都会创建新资源)
get没有请求体,post有请求体
两者之间没有本质区别,区别就在于数据存储的位置。

HTTP协议和HTTPS协议。
HTTP+加密+认证+完整性保护=HTTPS
HTTP协议是一种使用明文数据传输的网络协议。
HTTPS协议可以理解为HTTP协议的升级,就是在HTTP的基础上增加了数据加密。在数据进行传输之前,对数据进行加密,然后再发送到服务器。
在Http工作之前,Web浏览器通过网络和Web服务器建立链连接 通过Tcp来完成.
建立协议的时候,tcp进行了3次握手:
1、客户端发送了一个带有SYN的Tcp报文到服务器,这个三次握手中的开始。
2、服务端接收到客户端的请求,返回客户端报文,这个报文带有SYN和ACK标志,询问客户端是否准备好
3、客户端再次响应服务端一个ACK,表示我已经准备好。
当终止协议的时候,tcp进行了4次握手
HTTP协议的通信过程可以分为以下四个步骤:

  1. 浏览器根据IP地址和端口号与服务器建立连接
  2. 向Web服务器发送请求数据包
  3. Web服务器接收请求数据包后,发送相应的响应数据包
  4. 浏览器接收响应数据后关闭连接
    在这个过程中,一次请求对应一次连接,当浏览器再次发请求给服务器时,Web服务器并不知道这就是上次发请求的客户端,这也是HTTP协议的一个特点-无状态协议

内存溢出和内存泄漏的区别
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用
内存泄露 memory leak,内存泄漏就是应该释放而没有释放的内存

面向对象的三个重要特征: 封装 继承 多态

访问等级修饰符fileprivate,private, private(set) set , internal
private私有,本类的extension、其他类、继承都不能使用
fileprivate文件私有,本类文件内可以使用,文件外其他类、继承都不能使用
private(set) set方法私有,不能修改
internal(默认访问级别,internal修饰符可写可不写)如果是框架或者库代码,则在整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问
public公开 可以被任何人访问。但其他module中不可以被override和继承,而在module内可以被override和继承。
open开放 可以被任何人使用,包括override和继承。
open > public > interal > fileprivate > private

super关键字引用父类方法 属性
重写override 重写是子类继承父类,重写父类的方法。
重载overload
便利构造器(convenience)

属性观察者(willSet与didSet)
来监视属性的除初始化之外的属性值变化,当属性值发生改变时可以对此作出响应。有如下特点:
1,不仅可以在属性值改变后触发didSet,也可以在属性值改变前触发willSet。
2,给属性添加观察者必须要声明清楚属性类型,否则编译器报错。
3,willSet带一个newValue的参数,表示新的属性。
4,didSet带一个oldValue的参数,表示旧的属性。
5,属性初始化时,willSet和didSet不会调用。只有在初始化上下文之外,当设置属性值时才会调用。
6,即使是设置的值和原来值相同,willSet和didSet也会被调用
var myProperty: Int = 0 {
didSet {
print("myProperty 的值从 (oldValue) 更改为 (myProperty)")
}
}

setter、getter方法

final关键字在大多数的编程语言中都存在,表示不允许对其修饰的内容进行继承或者重新操作, final关键字可以在class、func和var前修饰。

Swift有特有的泛型 元祖概念

  1. Swift容易阅读,语法和文件结构简易化。
    2、Swift更易于维护,文件分离后结构更清晰。
    3、Swift更加安全,它是类型安全的语言。
    4、Swift代码更少,简洁的语法,可以省去大量冗余代码
    5、Swift速度更快,运算性能更高

Swift引入了可选项类型,用于处理变量值不存在的情况。Optionals类似于OC中指向nil的指针,但是适用于所有数据类型,而非仅仅局限于类,Optionals相比于OC中的nil指针,更加安全和简明,并且也是Swift诸多最强大功能的核心

Swift不再是OC的非0就是真,而是true才是真false才是假

strong修饰的指针变量指向对象时,当指针指向新值或者指针不复存在,相关联的对象就会自动释放,而weak修饰的指针变量指向对象,当对象的拥有者指向新值或者不存在时weak修饰的指针会自动置为nil。

原子性修饰符:atomic | nonatomic 读写性修饰符:readwrite | readonly setter相关修饰符:assign | retain | copy
用strong修饰OC对象以及NSString和Block , 没添加到父控件上的控件
用weak修饰已经被添加到父控件上的控件 以及 代理对象
用assign基本数据类型、枚举、结构体(非OC对象) class类型
用copy修饰一种情况下的NSString-->不确定赋值过程中用的是可变还是不可变字符串

block
//无参无返回值
typealias funcBlock = () -> () //或者 () -> Void
//返回值是String
typealias funcBlockA = (Int,Int) -> String
//返回值是一个函数指针,入参为String
typealias funcBlockB = (Int,Int) -> (String)->()
//返回值是一个函数指针,入参为String 返回值也是String
typealias funcBlockC = (Int,Int) -> (String)->String

AES 对称加密算法也就是加密和解密用相同的密钥
MD5主要特点是 不可逆,

Core Data

ObjectMapper

swift中的闭包和oc中的block
OC中的block是匿名的函数
Swift中的闭包是一个特殊的函数
block和闭包都经常用于回调
oc //例子
int (^sumOfNumbers)(int a, int b) = ^(int a, int b) {
return a + b;
};
swift 例子

typealiasBackValueBlock = (String)->()//声明一个闭包
var backValueBlock:BackValueBlock?;//把闭包声明成一个属性
self.backValueBlock = {
(Str) ->Void in
print(Str)
}
调用
if backValueBlock != nil {
backValueBlock!("swift send a value!!!!");
}

NSDictionary(字典)是使用 hash表来实现key和value之间的映射和存储的, hash函数设计的好坏影响着数据的查找访问效率。数据在hash表中分布的越均匀,其访问效率越高。而在Objective-C中,通常都是利用NSString 来作为键值,其内部使用的hash函数也是通过使用 NSString对象作为键值来保证数据的各个节点在hash表中均匀分布。

(1) setValue: ForKey:的value是可以为nil的(但是当value为nil的时候,会自动调用removeObject:forKey方法)
setObject: ForKey:的value则不可以为nil。
(2) setValue: ForKey:的key必须是不为nil的字符串类型;

集合(Set)
一个Set类型不能从数组字面量中被单独推断出来,因此Set类型必须显式声明。
存储的元素互不相同(若在集合中放入两个相同的元素,会自动过滤掉其中一个)
存储元素是无序的
存储元素必须是对象类型
集合是一种哈希表,运用散列算法,查找集合中的元素比数组速度更快

NSSet和NSArray功能性质一样,用于存储对象,属于集合。但是和NAArray不一样的是它属于 “无序集合”,在内存中存储方式是不连续的,而NSArray是 “有序集合” 它内存中存储位置是连续的
NSSet的效率确实是比NSArray高的,因为它主要用的是hash算法,我的理解中,NSSet在集合中寻找一个元素的时候是一针见血,找到目标顺着就去了;而NSArray的话需要循环集合中所有的对象,来找到所需要的目标。所以,循环所有对象与直接去对象的位置获取,速度就显而易见了

React Native 主要编程语言是JavaScript 跨平台开发

显式动画 隐式动画
显式动画是指用户自己通过beginAnimations:context:和commitAnimations创建的动画。
隐式动画是指通过UIView的animateWithDuration:animations:方法创建的动画。
使用隐式动画后,View会暂时不能接收用户的触摸、滑动等手势。

ios 动画

逐帧动画: 定时器实现 CADisplayLink:实现 gif动画效果

Core Animation-> CAPropertyAnimation ->CABasicAnimation 基础动画
transform. 缩放 scale 旋转 rotation 平移translation
let animation:CABasicAnimation = CABasicAnimation()
animation.keyPath = "transform.scale.x"
animation.fromValue = 1.0
animation.toValue = 0.8
animation.duration = 2.0
animation.fillMode = kCAFillModeForwards
animation.isRemovedOnCompletion = false
loginButton?.layer.add(animation, forKey: nil)

Core Animation-> CAPropertyAnimation ->CAKeyframeAnimation 关键帧动画
let circleKeyframePath = CGMutablePath()
circleKeyframePath.addLine(to: CGPoint(x: -100, y: 0), transform: circleKeyframeTransform)
let circleKeyframeAnimation:CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position")
circleKeyframeAnimation.path = circleKeyframePath
circleKeyframeAnimation.duration = 5
//让 Core Animation 向被驱动的对象施加一个恒定速度,不管路径的各个线段有多长。
circleKeyframeAnimation.calculationMode = kCAAnimationPaced
circleKeyframeAnimation.repeatCount = HUGE
//让它自身也做旋转,不过是圆的看不出效果
circleKeyframeAnimation.rotationMode = kCAAnimationRotateAutoReverse
//print(circleView.layer.anchorPoint)
circleView.layer.add(circleKeyframeAnimation, forKey: nil)
Core Animation-> CAAnimationGroup组动画
let rotate:CABasicAnimation = CABasicAnimation()
rotate.keyPath = "transform.rotation"
rotate.toValue = Float.pi
let scale:CABasicAnimation = 库CABasicAnimation()
scale.keyPath = "transform.scale"
scale.toValue = 0.0
let move:CABasicAnimation = CABasicAnimation()
move.keyPath = "transform.translation"
move.toValue = NSValue(cgPoint:CGPoint(x:217,y:-230))
let animationGroup:CAAnimationGroup = CAAnimationGroup()
animationGroup.animations = [rotate,scale,move];
animationGroup.duration = 2.0;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.isRemovedOnCompletion = false
loginButton?.layer.add(animationGroup, forKey:nil)

CATransition转场动画
present控制器 跳转动画效果 可自定义 modalTransitionStyle
Spring动画

获取上下文绘制颜色为图片
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!

iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。
NSTimer 的精确度就显得低了点,比如 NSTimer 的触发时间到的时候,runloop 如果在阻塞状态,触发时间就会推迟到下一个 runloop 周期。并且 NSTimer 新增了 tolerance 属性,让用户可以设置可以容忍的触发的时间的延迟范围。
CADisplayLink 使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer 的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink 比起用 NSTimer 的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。

setNeedsLayout与layoutIfNeeded的区别
更新布局总会重新触发layoutSubviews方法。
layoutSubviews 继承于UIView的子类重写,进行布局更新,刷新视图. 如果某个视图自身的bounds或者子视图的bounds发生改变,那么这个方法会在当前runloop结束的时候被调用。
setNeedsLayout
标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,在下一轮runloop结束前刷新,对于这一轮runloop之内的所有布局和UI上的更新只会刷新一次,layoutSubviews一定会被调用。
layoutIfNeeded
如果有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)。

  • layoutIfNeeded不一定会调用layoutSubviews方法。
  • setNeedsLayout一定会调用layoutSubviews方法(有延迟,在下一轮runloop结束前)。

沙盒standbox,其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中。在沙盒机制下,每个程序之间的文件夹不能互相访问
Documents,Library (Caches 和 Preferences),tmp

数据存储方式
1 . plist 存储
let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let path = NSString(string: documentPath).appendingPathComponent(documentPath)
let dic:NSDictionary = ["name":"322"]
dic.write(toFile: path, atomically: true)
let d = NSDictionary(contentsOfFile: path)
2.偏好设置存储
let defaults = UserDefaults.standard
KUserDefauls.set(0000, forKey: “age”)
(KUserDefauls.value(forKey: "age") as? Int)
3.归档 需要保存的对象必须遵守NSCoding协议,并且实现该协议中- (void)encodeWithCoder:(NSCoder )aCoder和 - (id)initWithCoder:(NSCoder )aDecoder方法。
Swift4 之后只需要你的model遵守Codable协议
let data = try PropertyListEncoder().encode(object)
let success = NSKeyedArchiver.archiveRootObject(data, toFile: path)
let data = NSKeyedUnarchiver.unarchiveObject(withFile: path)
4.SQLITE数据库

  1. FMDB
    6.CoreData

swift 多线程
Thread、GCD、OperationQueue
耗时操作 网络请求 图片加载
let operationQ = OperationQueue()
let blockOp1 = BlockOperation()
blockOp1.addExecutionBlock {
print("11111执行addExecutionBlock")
}
operationQ.addOperation(blockOp1)

Thread.sleep(forTimeInterval: 1.0)//线程休眠

买票 加锁
func buyticket(){
var ticket = 11110
DispatchQueue.global().async {
objc_sync_enter(ticket)
let count = ticket - 1
ticket = count
objc_sync_exit(ticket)
}
}
asyncAfter
queue.asyncAfter(wallDeadline: .now() + time) {
print("wall dead line done")
}
queue.asyncAfter(deadline: .now() + time) {
print("dead line done")
}
wallDeadline 和 deadline,当系统睡眠后,wallDeadline会继续,但是deadline会被挂起。

线程安全
objc_sync_enter(ticket) objc_sync_exit(ticket)
NSCondition lock unlock wait signal
DispatchSemaphore 最大并发量机制 信号量

内存管理
Ios中数据是存在在堆和栈中的, 管理的是堆上的内存 基础数据类型再栈上, oc对象在堆上
栈 系统去管理。地址从高到低分配。先进后出。
堆 需要我们自己管理内存,alloc申请内存release释放内存。创建的对象也都放在这里。 地址是从低到高分配。
全局区(静态区) 常量区 代码区
MRC
当创建一个对象的实例并在堆上申请内存时,对象的引用计数就为1,在其他对象中需要持有这个对象时,就需要把该对象的引用计数加1,需要释放一个对象时,就将该对象的引用计数减1,直至对象的引用计数为0,对象 的内存会被立刻释放。
ARC (自动引用计数)
内存的管理由系统进行接管

swift arc的三种引用
强引用(strong reference):默认情况下,代码中涉及到的引用都是强引用

  • 弱引用(weak reference):通过weak定义弱引用
  • 无主引用(unowned reference):通过unowned定义无主引用
    weak、unowned都能解决循环引用的问题,unowned要比weak少一些性能消耗
  • 在生命周期中可能会变为nil的使用weak
  • 初始化赋值后再也不会变为nil的使用unowned
    想在引用闭包的同时引用self, 这个闭包必须是lazy的

内存访问冲突
同时对定义的变量执行读写操作
swift 中的指针类型 定性为Unsafe 类型有UnsafePointer等
// 创建指针
var ptr = malloc(16)

僵尸对象:内存已经被回收的对象。
野指针:指向僵尸对象的指针,向野指针发送消息会导致崩溃。野指针错误形式在Xcode中通常表现为:Thread 1:EXC_BAD_ACCESS,因为你访问了一块已经不属于你的内存。
C语言 指向1块随机的空间.这个指针就叫做野指针

环信是一个即时通讯的服务提供商
环信使用的是XMPP协议,它是再XMPP的基础上进行二次开发 基于Socket的网络通信

ViewController生命周期:

  1. viewDidLoad 2. viewWillAppear 3 viewDidAppear 4 viewWillDisappear 5viewDidDisappear
    viewDidUnload 在发生内存警告时 本视图不在当前展示的视图上

swift Mutating 可改变
在 1.结构体 枚举类型中声明修饰方法 2.在estension protocol修饰方法
加 mutating就可以修改属性变量

weak属性修饰词解析
__weak修饰变量 weak 防止block循环引用

UIView和CALayer是啥关系
首先UIView可以响应事件,Layer不可以. UIView 继承 UIResponder,而 UIResponder 是响应者对象
UIView是CALayer的delegate
UIView主要处理事件,CALayer负责绘制
anchorPoint 和 position
anchorPoint 锚点是相对于当前 Layer 的一个点,position 是 Layer 中 anchorPoint 锚点在 superLayer 中的点,position 是由 anchorPoint 来确认的。

声明property的时候,有2个选择
1:通过@synthesize 指令bai告诉编du译器在编译期间产zhi生getter/setter方法。
2:通过@dynamic指令,自己实现方法。

@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字
我们把一个变量定义成NSString,那一定是我们不希望它的值被任意改变。如果定义属性的时候使用strong,那就有可能存在被任意,或者意料之外改动的情况。

static:用于声明一个静态的变量;
A.一般是修饰全局变量,改变全局变量作用域,目的是防止重复声明全局变量。能够隐藏变量和函数;
B.共有两种变量存储在静态存储区:全局变量和static变量,存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。
C.static的第三个作用是默认初始化为0.
D.和const使用代替宏:如果使用static和const组合使用,不可以修改变量的值,否则编译器报错

swift 匹配模式
除了可以匹配枚举类型外,支持更多的原生类型匹配,包过Int、String、Float、Tuple、Range等
可以对类型进行匹配,配合 as、is 来使用
重载匹配操作符~=,可以支持自定义类型的匹配操作
可结合where、if、guard、for来使用
对Optional类型的匹配

对枚举的匹配
enum Weather {
case rain, snow, wind, sunny
}
let todayWeather = Weather.rain
switch todayWeather {
case .rain , sonw:
print("下雨huo下雪)
case .snow:
print("下雪")
case .wind:
print("刮风")
case .sunny:
print("晴天")
}
枚举匹配时还可以绑定枚举的关联值:
enum Weather {
case rain(level: Int), snow(level: Int), wind(level: Int), sunny
}

let todayWeather = Weather.rain(level: 1)

switch todayWeather {
case .rain(let level):
if level > 10 {
print("大雨")
}else {
print("小雨")
}
}

// 这两种写法是等价的
case .rain(let level):
case let .rain(level):

switch todayWeather {
case let .rain(_, duration) where duration == 24:
print("全天有雨")
case let .rain(level, _) where level > 10:
print("大雨")
case let .rain(level, _) where level < 10:
print("小雨")
default:
break
}

swift 除了 enum 和 int类型之外,还支持多种原生类型的匹配:String,Tuple,Range等

类型匹配 用到两个关键字 is、as
switch animal {
case let dog as Dog:
print("(dog.name) can run (dog.runSpeed)")
case let fish as Fish:
print("(fish.name) can dive depth (fish.depth)")
case is Bird:
print("bird can fly!")
default:
print("unknown animal!")
}

Optional 匹配

元祖 puple
var aTuple = (index: 10, name: "Xishi")

tableview的优化

  1. 将赋值和计算布局分离 根据数据源计算布局, 并把布局缓存到数据源中
  2. 避免使用layer的border、corner、shadow、mask 等技术 尽量在后台线程预先绘制好对应内容
  3. 当滚动停止是加载可见cell的图片
  4. 异步绘制
  • 正确使用重用机制
  • 尽量少用或者不用透明图层
  • 减少subviews的数量
  • 如果Cell内部的内容来自web,使用异步加载,缓存请求结果

runloop 运行循环
是程序持续运行 节约cpu资源 提高程序性能 处理各种事件(touch 定时器 performselectord)
作用用来管理线程 主线程的runloop是默认开启的

App生命周期
Not running Inactive Active Background Suspended

当声明一个带有闭包参数的函数时,可以将@escaping写在参数类型前面,指明该闭包允许逃离函数。
@autoclosure 作用就是简化闭包调用形式。
@autoclosure 并不支持带有输入参数的写法,也就是说只有形如 () -> T 的参数才能使用这个特性进行简化
@escaping 是闭包的另一个修饰符。当闭包的某个参数在闭包返回后才被调用时称这个参数是逃逸的参数
对于可以逃逸的闭包参数,其实现内部必须显式使用 self 引用,而非逃逸闭包参数则可以隐式使用 self 引用。
class SomeClass{
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 }
someFunctionWithNonescapingClosure { x = 200 }
}

func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

}

异常抛出关键 throws 定义在函数结尾 如果函数有返回值 定义在 返回类型前

@discardableResult 通配符_ 取消”返回值未使用” 的警告

约束的优先级
priorityLow():设置低优先级,优先级为250
priorityMedium():设置中优先级,优先级为500(这个也就是默认的优先级)
priorityHigh():设置高优先级,优先级为750
priority():可以设置任意的优先级,接受的参数是0-1000的数字。比如:priority(600)

相关文章

网友评论

      本文标题:2020-11-23

      本文链接:https://www.haomeiwen.com/subject/xmmowftx.html