push pop 和 present dismiss

push/pop 和 present/dismiss

文章目录

  • push/pop 和 present/dismiss
  • 前言
  • push / pop
  • present
    • 普通的present
    • 多层present
      • 多层present后的父子关系问题
      • 多层弹出会遇到的问题
    • showViewController 和 showDetailViewController
      • showViewController
      • showDetailViewController
  • dismiss
  • 模态化

前言

之前曾经在网易云仿写总结中,使用过present制作抽屉视图的展示,在这里再次详细对比一下push和present的区别

想象一下你正在看一本书,随着你读书的进度不断增加,你的页数也越来越多,这就是导航栏带来的逐层深入。

突然,你需要查一个重要的词语解释。你会从桌上拿起一本字典,把它放在你正在看的书页上,然后开始查找。这本字典就是你的模态视图,它暂时遮住了你正在看的书页(在iOS13之后,present出的页面的模态样式变为了UIModelPresentationAutomatic,新的页面将不再完全覆盖之前的页面,而只会部分遮挡,并且允许你向下拖动关闭)

push / pop

push的操作必须在一个UINavigationController的上下文中进行,导航控制器会维护一个栈,当push后,一个新的view会被压入到栈顶,同时导航控制器会自动添加一个按钮用于返回

因为push的弹出新界面是由于视图栈的顶部有更换,所以你对视图的添加和删除要完全符合栈的操作

你可以pop到指定视图,苹果也提供了相关方法(实际上用户只要长按返回按钮就可以返回到之前的指定页面)

请添加图片描述

popToViewController:animated: pop到指定的界面

popToRootViewControllerAnimated: 一直pop到根视图停止

但是你无法只删除栈中的某一页面

在pop时,对应的新视图会先调用viewDidLoad 方法,然后是viewWillAppear 最后是viewDidAppear

present

普通的present

从iOS13开始,present为了适配卡片风格展示,模态默认样式变为UIModelpresentationAutomatic 新的视图为部分覆盖

present本质是在新的视图上重新呈现了一个视图,当前的视图只能通过自己dismiss来返回原来的视图,同时,新旧视图之间是有层级关系的

源码:

// The view controller that was presented by this view controller or its nearest ancestor.
@property(nullable, nonatomic,readonly) UIViewController *presentedViewController  API_AVAILABLE(ios(5.0));// The view controller that presented this view controller (or its farthest ancestor.)
@property(nullable, nonatomic,readonly) UIViewController *presentingViewController API_AVAILABLE(ios(5.0));

可以看出,两个属性都没有加入内存类的属性关键字,所以都为strong强引用

所以在present视图之后,父视图和子视图会形成循环强引用,只有在新的视图被dismiss之后,才会断开循环引用

- (void)presentBlueBlackThenRed {UIViewController *vcBlue = [[UIViewController alloc] init];vcBlue.view.backgroundColor = [UIColor systemBlueColor];NSLog(@"准备呈现蓝色视图...");[self presentViewController:vcBlue animated:YES completion:^{UIViewController *vcBlack = [[UIViewController alloc] init];vcBlack.view.backgroundColor = [UIColor blackColor];[vcBlue presentViewController:vcBlack animated:YES completion:^{UIViewController *vcRed = [[UIViewController alloc] init];vcRed.view.backgroundColor = [UIColor systemRedColor];[vcBlack presentViewController:vcRed animated:YES completion:nil];}];}];NSLog(@"vcBlue的父视图是否为self? %@", [vcBlue.presentingViewController isEqual:self] ? @"YES" : @"NO");NSLog(@"self的子视图是否为vcBlue? %@", [self.presentedViewController isEqual:vcBlue] ? @"YES" : @"NO");
}

控制台输出!:
请添加图片描述

多层present

在一个已经被present的视图中再次present一个视图,是多层的present

之前我们也讲过,present的主视图和新的视图是强引用,所以如果过多的present视图,可能会导致内存泄露等等问题

present出的视图,是模态视图,在什么时候使用模态视图会在后面讲

但是不管是什么情况,都不建议使用多层的present

多层present后的父子关系问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意看,这张图里,VCA present了 VCB,VCB present了 VCC

并且A带有了导航控制器

- (void)presentBlueBlackThenRed {UIViewController *vcBlue = [[UIViewController alloc] init];vcBlue.view.backgroundColor = [UIColor systemBlueColor];UINavigationController* blueNavi = [[UINavigationController alloc] initWithRootViewController:vcBlue];NSLog(@"准备呈现蓝色视图...");[self presentViewController:blueNavi animated:YES completion:^{NSLog(@"vcBlue的父视图是否为self? %@", [vcBlue.presentingViewController isEqual:self] ? @"YES" : @"NO");NSLog(@"self的子视图是否为vcBlue? %@", [self.presentedViewController isEqual:vcBlue] ? @"YES" : @"NO");UIViewController *vcBlack = [[UIViewController alloc] init];vcBlack.view.backgroundColor = [UIColor blackColor];[vcBlue presentViewController:vcBlack animated:YES completion:^{NSLog(@"vcBlack的父视图是否为vcBlue? %@", [vcBlack.presentingViewController isEqual:vcBlue] ? @"YES" : @"NO");NSLog(@"vcBlack的父视图是否为vcBlue的导航栏? %@", [vcBlack.presentingViewController isEqual:vcBlue.navigationController] ? @"YES" : @"NO");NSLog(@"vcblue的子视图是否为vcBlack? %@", [vcBlue.presentedViewController isEqual:vcBlack] ? @"YES" : @"NO");UIViewController *vcRed = [[UIViewController alloc] init];vcRed.view.backgroundColor = [UIColor systemRedColor];[vcBlack presentViewController:vcRed animated:YES completion:^{NSLog(@"vcRed的父视图是否为vcBlack? %@", [vcRed.presentingViewController isEqual:vcBlack] ? @"YES" : @"NO");NSLog(@"vcblack的子视图是否为vcRed? %@", [vcBlack.presentedViewController isEqual:vcRed] ? @"YES" : @"NO");}];}];}];[vcBlue dismissViewControllerAnimated:YES completion:nil];}

请问,B的presentingView(即父视图)是谁?

答案是A的导航控制器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

重新阅读presentingViewpresentedView 属性中给到的注释:

// The view controller that was presented by this view controller or its nearest ancestor.
// The view controller that presented this view controller (or its farthest ancestor.)

// 由该视图控制器或其最近的祖先呈现的视图控制器。
// 展示此视图控制器(或其最远祖先)的视图控制器。

注释中提到“or its nearest/farthest ancestor”,意思是这两个属性的值不一定是和弹操作直接关联的视图控制器

Apple官方文档也显示

Support for presenting view controllers is built in to the UIViewControllerclass and is available to all view controller objects. You can present any view controller from any other view controller, although UIKit might reroute the request to a different view controller.

UIViewController类中内置了对显示视图控制器的支持,并且适用于所有视图控制器对象。您可以从任何其他视图控制器呈现任何视图控制器,尽管UIKit可能会将请求重定向到其他视图控制器。

所以实际上你的新视图会根据视图的层级关系来调整到底是谁去presentingView,谁来当新视图的presentingView

有的博客提到了UIKit会根据你的新页面的弹出方式来判断谁去当presentingView,即如果是全屏,UIKit会寻找父视图上是全屏的VC作为新视图的presentingView,但是我这里敲过例子后发现不会,并且即使设置了definesPresentationContext,视图层级也不会变化

- (void)presentBlueBlackThenRed {UIViewController *vcBlue = [[UIViewController alloc] init];vcBlue.view.backgroundColor = [UIColor systemBlueColor];UINavigationController* blueNavi = [[UINavigationController alloc] initWithRootViewController:vcBlue];NSLog(@"准备呈现蓝色视图...");// 推出导航控制器来让blue有自己的导航控制器,测试是否会由于导航控制器影响子视图的presentingView[self presentViewController:blueNavi animated:YES completion:^{NSLog(@"vcBlue的父视图是否为self? %@", [vcBlue.presentingViewController isEqual:self] ? @"YES" : @"NO");NSLog(@"self的子视图是否为vcBlue? %@", [self.presentedViewController isEqual:vcBlue] ? @"YES" : @"NO");UIViewController *vcBlack = [[UIViewController alloc] init];vcBlack.view.backgroundColor = [UIColor blackColor];// 这里进行修改// vcBlue.definesPresentationContext = YES;vcBlack.modalPresentationStyle = UIModalPresentationFullScreen;[vcBlue presentViewController:vcBlack animated:YES completion:^{NSLog(@"vcBlack的父视图是否为vcBlue? %@", [vcBlack.presentingViewController isEqual:vcBlue] ? @"YES" : @"NO");NSLog(@"vcBlack的父视图是否为vcBlue的导航栏? %@", [vcBlack.presentingViewController isEqual:vcBlue.navigationController] ? @"YES" : @"NO");NSLog(@"vcblue的子视图是否为vcBlack? %@", [vcBlue.presentedViewController isEqual:vcBlack] ? @"YES" : @"NO");UIViewController *vcRed = [[UIViewController alloc] init];vcRed.view.backgroundColor = [UIColor systemRedColor];[vcBlack presentViewController:vcRed animated:YES completion:^{NSLog(@"vcRed的父视图是否为vcBlack? %@", [vcRed.presentingViewController isEqual:vcBlack] ? @"YES" : @"NO");NSLog(@"vcblack的子视图是否为vcRed? %@", [vcBlack.presentedViewController isEqual:vcRed] ? @"YES" : @"NO");//                NSLog(@"推出");
//                [vcRed dismissViewControllerAnimated:YES completion:nil];
//                [vcRed.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];}];}];}];//    [vcBlue dismissViewControllerAnimated:YES completion:nil];}

这里我使用了全屏展示的样式,但是vcBlack的presentingView还是vcBlue

之后在设置definesPresentationContext属性为YES,并加入导航控制器后,vcBlack的presentingView也没有变为vcBlue,而是重新定位到了vcBlue的导航控制器上

这个地方确实找不到其他的博客了,所以我先放在这里,期望会的大佬帮忙解答一下,感谢!

多层弹出会遇到的问题

还是刚刚的例子

在A视图推出B视图,如果想呈现C视图,应该使用B视图来推出对吧

但是如果我使用A视图推出会发生什么呢?

- (void)presentBlueBlackThenRed {UIViewController *vcBlue = [[UIViewController alloc] init];vcBlue.view.backgroundColor = [UIColor systemBlueColor];UINavigationController* blueNavi = [[UINavigationController alloc] initWithRootViewController:vcBlue];NSLog(@"准备呈现蓝色视图...");// 推出导航控制器来让blue有自己的导航控制器,测试是否会由于导航控制器影响子视图的presentingView[self presentViewController:blueNavi animated:YES completion:^{NSLog(@"vcBlue的父视图是否为self? %@", [vcBlue.presentingViewController isEqual:self] ? @"YES" : @"NO");NSLog(@"self的子视图是否为vcBlue? %@", [self.presentedViewController isEqual:vcBlue] ? @"YES" : @"NO");UIViewController *vcBlack = [[UIViewController alloc] init];vcBlack.view.backgroundColor = [UIColor blackColor];// 这里进行修改vcBlue.definesPresentationContext = YES;
//        vcBlack.modalPresentationStyle = UIModalPresentationFullScreen;[vcBlue presentViewController:vcBlack animated:YES completion:^{NSLog(@"vcBlack的父视图是否为vcBlue? %@", [vcBlack.presentingViewController isEqual:vcBlue] ? @"YES" : @"NO");NSLog(@"vcBlack的父视图是否为vcBlue的导航栏? %@", [vcBlack.presentingViewController isEqual:vcBlue.navigationController] ? @"YES" : @"NO");NSLog(@"vcblue的子视图是否为vcBlack? %@", [vcBlue.presentedViewController isEqual:vcBlack] ? @"YES" : @"NO");UIViewController *vcRed = [[UIViewController alloc] init];vcRed.view.backgroundColor = [UIColor systemRedColor];vcRed.modalPresentationStyle = UIModalPresentationFullScreen;[vcBlue presentViewController:vcRed animated:YES completion:^{NSLog(@"vcRed的父视图是否为vcBlack? %@", [vcRed.presentingViewController isEqual:vcBlack] ? @"YES" : @"NO");NSLog(@"vcblack的子视图是否为vcRed? %@", [vcBlack.presentedViewController isEqual:vcRed] ? @"YES" : @"NO");//                NSLog(@"推出");
//                [vcRed dismissViewControllerAnimated:YES completion:nil];
//                [vcRed.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];}];}];}];//    [vcBlue dismissViewControllerAnimated:YES completion:nil];}

控制台输出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

并且红色视图不会被弹出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用present去弹模态视图的时候,只能用最顶层的的控制器去弹,用底层的控制器去弹会失败,并抛出警告

(当然是有邪修方法的)

如果一个viewController的view还没被添加到视图树(父视图)上,那么用这个viewController去present会失败,并抛出警告。

如果你非要这么写的话,可以把present的部分放到-viewDidAppear方法中,因为-viewDidAppear被调用时self.view已经被添加到视图树中了(强烈不推荐)

正确的做法应该是使用childViewController,你可以用添加子视图、子控制器的方式来实现类似效果

- (void)viewDidLoad {[super viewDidLoad];_BViewController = [[UIViewController alloc] init];_BViewController.view.frame = self.view.bounds;[self.view addSubview:_BViewController.view];[self addChildViewController:_BViewController];  //这句话一定要加,否则视图上的按钮事件可能不响应
}

showViewController 和 showDetailViewController

在阅读苹果的《Presenting a View Controller》时,找到了这两个方法,在这里进行简单的区分

showViewController

showViewController:sender: 这个方法,可以说是 UIKit 框架为了适应不同尺寸屏幕(尤其是为了 iPad)而设计的一个“智能”导航方法,它和 presentViewController: 的区别,就像是智能导航指定路线的区别

presentViewController: 这个方法就是在对系统下达死命令,不管怎么样,你的视图必须以模态视图的方法弹出,它的行为是固定的,结果是可预期的

showViewController:sender: 这个方法不是在下达死命令,而是在向系统阐述一个需求:我希望把这个视图控制器展示给用户,请你根据当前的环境,用最合适的方式把它显示出来

这个“当前的环境”是什么呢?主要是指当前的视图控制器层级

  • 如果当前 VC 在 UINavigationController 里:系统会认为“最合适”的方式是 push。所以 showViewController: 的效果就等同于 [self.navigationController pushViewController:vc animated:YES]
  • 如果当前 VC 不在 UINavigationController 里:系统找不到可以 push 的“轨道”,就会认为“最合适”的方式是 present。所以 showViewController: 的效果就等同于 [self presentViewController:vc animated:YES completion:nil]
  • 在 iPad 的 SplitViewController 环境下:情况会更复杂。如果你的 App 在分屏模式下运行,showViewController: 可能会在一个窗格里 push 一个视图,也可能会在另一个窗格里 present一个视图,完全取决于 Split View Controller 的当前状态和结构。它会自动适应,选择最符合 iPadOS 人机交互规范的方式

showDetailViewController

showDetailViewController: 是一个**专门用于“主从式”界面的、目的性更强的“智能导航”,**它的用处,几乎完全绑定在 UISplitViewController 这种视图容器上

它所表达的意思就是,把这个视图控制器,显示在‘详情’区域!

这个基本上只用于ipad,所以这里就不展开描述了,只做了解即可

dismiss

首先需要明确一个事情,A弹出B,然后在B中执行dismissViewControllerAnimated:completion: 这个很常见的流程实际上是错的

之所以我们可以这么做,实际上是因为UIKit会帮我们自动通知父视图dismiss

一般,大家也都是这么用的,A弹B,B中调用dismiss消失弹框。没问题。

那,A弹B,我在A中调用dismiss可以吗?——也没问题,B会消失。

那,A弹B,B弹C。A调用dismiss,会有什么样的结果?是C消失,还是B、C都消失,还是会报错? ——正确答案是B、C都消失

如果B掉dismiss呢?B会消失吗?——答案是:只有C会消失,B不会消失

还是上面的代码

- (void)presentBlueBlackThenRed {UIViewController *vcBlue = [[UIViewController alloc] init];vcBlue.view.backgroundColor = [UIColor systemBlueColor];UINavigationController* blueNavi = [[UINavigationController alloc] initWithRootViewController:vcBlue];NSLog(@"准备呈现蓝色视图...");// 推出导航控制器来让blue有自己的导航控制器,测试是否会由于导航控制器影响子视图的presentingView[self presentViewController:blueNavi animated:YES completion:^{NSLog(@"vcBlue的父视图是否为self? %@", [vcBlue.presentingViewController isEqual:self] ? @"YES" : @"NO");NSLog(@"self的子视图是否为vcBlue? %@", [self.presentedViewController isEqual:vcBlue] ? @"YES" : @"NO");UIViewController *vcBlack = [[UIViewController alloc] init];vcBlack.view.backgroundColor = [UIColor blackColor];// 这里进行修改
//        vcBlue.definesPresentationContext = YES;
//        vcBlack.modalPresentationStyle = UIModalPresentationFullScreen;[vcBlue presentViewController:vcBlack animated:YES completion:^{NSLog(@"vcBlack的父视图是否为vcBlue? %@", [vcBlack.presentingViewController isEqual:vcBlue] ? @"YES" : @"NO");NSLog(@"vcBlack的父视图是否为vcBlue的导航栏? %@", [vcBlack.presentingViewController isEqual:vcBlue.navigationController] ? @"YES" : @"NO");NSLog(@"vcblue的子视图是否为vcBlack? %@", [vcBlue.presentedViewController isEqual:vcBlack] ? @"YES" : @"NO");UIViewController *vcRed = [[UIViewController alloc] init];vcRed.view.backgroundColor = [UIColor systemRedColor];vcRed.modalPresentationStyle = UIModalPresentationFullScreen;[vcBlack presentViewController:vcRed animated:YES completion:^{NSLog(@"vcRed的父视图是否为vcBlack? %@", [vcRed.presentingViewController isEqual:vcBlack] ? @"YES" : @"NO");NSLog(@"vcblack的子视图是否为vcRed? %@", [vcBlack.presentedViewController isEqual:vcRed] ? @"YES" : @"NO");NSLog(@"推出");
//                [vcRed dismissViewControllerAnimated:YES completion:nil];[vcRed.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];}];}];}];//    [vcBlue dismissViewControllerAnimated:YES completion:nil];}

我在弹出vcRed之后,用vcRed的presentingViewController的presentingViewController来进行dismiss操作

vcRed的presentingViewController是vcBlack,vcBlack的presentingViewController是vcBlue的导航控制器

按照理论来说,我们这里应该弹出全部的视图,也就是整个页面应该回到白色

但实际上:

在这里插入图片描述

可以观察到蓝色视图并没有弹出

阅读官方文档关于这个方法的解释:

To dismiss a presented view controller, call the dismissViewControllerAnimated:completion: method of the presenting view controller. You can also call this method on the presented view controller itself. When you call the method on the presented view controller, UIKit automatically forwards the request to the presenting view controller.

文档指出

1. 父节点负责调用dismiss来关闭他弹出来的子节点,你也可以直接在子节点中调用dismiss方法,UIKit会通知父节点去处理

2. 如果你连续弹出多个节点,应当由最底层的父节点调用dismiss来一次性关闭所有子节点;如果中间节点调dismiss,中间节点上面的节点都会消失,但中间几点本身并不会消失,这里要注意

3. 关闭多个子节点时,只有最顶层的子节点会有动画效果,下层的子节点会直接被移除,不会有动画效果

模态化

模态化是一种在单独的专用模式中呈现内容的设计技术,这种模式可阻止与父视图交互且需要进行确切的操作来关闭

以模态化方式呈现内容可以:

  • 确保用户接收关键信息,并在必要时对其进行操作
  • 提供选项以让用户确认或修改其最近的操作
  • 帮助用户执行明确的小范围任务,同时不会忘记其之前的环境
  • 向用户提供沉浸式体验,或帮助其专注于复杂任务

使用场景:

仅在必要时使用模态化。模态体验打断用户当前流程且需要额外操作关闭,因此只在需要用户专注或做出重要选择时使用

保持模态任务简短。复杂的模态任务可能导致用户忘记原任务,尤其是当模态视图完全覆盖原界面时

避免"App中的App"体验。若模态任务需要子视图,提供单一导航路径,避免使用可能被误认为关闭按钮的元素

复杂任务用全屏模态。全屏模态减少干扰,适用于视频、照片、相机或多步骤任务。

提供明显的关闭方式。遵循平台惯例:iOS/iPadOS/watchOS上通常在顶部工具栏或下滑手势,macOS和tvOS则在主视图中

关闭前避免数据丢失。若关闭可能丢失用户内容,提供解释和解决方案,如iOS中的存储选项操作表单

任务目的要清晰。提供清晰标题或描述,帮助用户理解当前位置和任务目标

避免同时展示多个模态视图。多模态视图会造成视觉混乱和认知负担,尤其是模态视图叠加时。提醒虽可显示在其他内容之上,但不应同时显示多个

参考文献:

  1. https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/PresentingaViewController.html#//apple_ref/doc/uid/TP40007457-CH14-SW1
  2. https://developer.apple.com/cn/design/human-interface-guidelines/modality
  3. https://www.jianshu.com/p/dd6180bc340a
  4. https://juejin.cn/post/6844903708799533063#heading-4

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

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

相关文章

服务器异常负载排查手册 · 隐蔽进程篇

适用范围 适用于 Linux 3.10 生产环境,发现 load 高但用户态 CPU 接近 0 % 的场景。1. 现场冻结目标:在 rootkit 干预前保存易失数据。#!/bin/bash # freeze.sh TS$(date %s) mkdir -p /srv/ir/${TS} cd /srv/ir/${TS}# 1.1 进程树(busybox 静…

2024理想算法岗笔试笔记

要理解指令微调(Instruction Tuning),需要先将其置于大语言模型(LLM)的训练框架中 —— 它并非模型训练的起点,而是针对 “让模型更懂人类需求” 的关键优化步骤。简单来说,指令微调是通过让模型…

Oracle 11g离线安装依赖包完整解决方案

本文还有配套的精品资源,点击获取 简介:Oracle 11g是一款广泛使用的关系型数据库管理系统,在离线环境下安装时需依赖多个系统库和工具。本“oracle11g依赖包”压缩文件包含了在CentOS 7.7上安装Oracle 11g可能缺失的关键依赖RPM包&#xf…

VBA数据结构选型:效率差5倍的生死抉择

VBA性能生死局:Dictionary与Collection效率差5倍!90%开发者用反血亏“你以为Collection是VBA的‘轻量级选手’?大错特错!实测数据显示:在10万级数据循环中,Dictionary的查询速度比Collection快5倍&#xff…

电机控制(四)-级联PID控制器与参数整定(MATLABSimulink)

PID算法 普通PID(Proportional-Integral-Derivative) 通过比例(P)、积分(I)和微分(D)三项来进行控制 比例项(P):根据当前误差(目标值…

数据结构深度解析:二叉树的基本原理

在数据结构体系中,树是一种重要的非线性层次结构,它通过 “节点” 与 “边” 的连接关系,模拟了现实世界中树的分支结构,能够高效地解决数据的查找、插入、删除等问题。而二叉树作为树结构中最简单、应用最广泛的类型,…

【React】Ant Design 5.x 实现tabs圆角及反圆角效果

需要实现的效果实现思路 利用tab页的before和after属性&#xff0c;添加tab页前后的圆弧属性&#xff0c;同时使用tab页的shadow阴影填充右下角的圆弧空缺部分。<TabsonChange{onChange}type"card"items{getTabItems()}/>.ant-tabs-nav{margin: 0;.ant-tabs-na…

WordPress过滤文章插入链接rel属性noopener noreferrer值

WordPress过滤文章插入链接rel属性noopener noreferrer值在保存文章的时候&#xff0c;WordPress会自动过滤文章内容中的链接&#xff0c;具有target属性的链接会自动添加rel"noopener noreferrer"&#xff0c;该属性是为了预防跨站攻击&#xff0c;站内链接似乎没有…

make_shared的使用

目录 1. make_shared 的基本概念 基本用法 2. 引入 make_shared 的主要原因 2.1 解决传统构造方式的问题 2.2 标准委员会的动机 3. make_shared 的核心优势 3.1 性能优势&#xff08;最重要优点&#xff09; 内存分配优化&#xff1a; 性能提升表现&#xff1a; 3.2 异…

基于 Gemini 的 CI/CD 自动化测评 API 集成实战教程

在现代软件开发中&#xff0c;CI/CD 集成 已经成为必不可少的流程。它不仅能帮助团队快速迭代&#xff0c;还能通过自动化手段提升代码质量。而在编程培训和团队内部学习中&#xff0c;如何引入 自动化测评 API&#xff0c;实现提交即测评、即时反馈呢&#xff1f;本文将以 Gem…

SOME/IP-SD(Service Discovery)协议的核心协议

<摘要> 本解析以AutoSAR AP R22-11版本为基准&#xff0c;全面系统地阐述了SOME/IP-SD&#xff08;Service Discovery&#xff09;协议的核心内容。从车载网络演进背景切入&#xff0c;详细剖析了面向服务架构&#xff08;SOA&#xff09;下服务发现的必要性&#xff0c;…

视频串行解串器(SerDes)介绍

视频串行解串器&#xff08;SerDes&#xff09;是高速数据通信中的核心接口技术&#xff0c;通过串行化与解串行化实现视频信号的高效传输&#xff0c;广泛应用于汽车电子、数据中心、高清视频传输等领域。 一、技术原理串行化&#xff08;Serializer&#xff09; 功能&#xf…

哈士奇vs网易高级数仓:数据仓库的灵魂是模型、数据质量还是计算速度?| 易错题

面试场景 面试官: (微笑,营造轻松但专业的氛围)嗨,哈士奇,欢迎来参加网易的二面。我看你简历上数据仓库的项目经验很丰富,我们今天就深入聊聊。我这里有一个经典的问题想听听你的看法:在你看来,数据仓库的灵魂是模型、数据质量还是计算速度? 哈士奇: (不假思索,…

贪心算法应用:3D打印支撑结构问题详解

Java中的贪心算法应用&#xff1a;3D打印支撑结构问题详解 1. 问题背景与概述 1.1 3D打印中的支撑结构问题 在3D打印过程中&#xff0c;当模型存在悬空部分&#xff08;overhang&#xff09;时&#xff0c;通常需要添加支撑结构&#xff08;support structure&#xff09;来防止…

Python爬虫实战:研究3D plotting模块,构建房地产二手房数据采集和分析系统

1. 引言 1.1 研究背景 在大数据与人工智能技术快速发展的背景下,数据已成为驱动决策的核心要素。互联网作为全球最大的信息载体,蕴含海量结构化与非结构化数据,如何高效提取并分析这些数据成为学术界与产业界的研究热点。 网络爬虫技术通过自动化请求与解析网页,实现数据…

Gradio全解10——Streaming:流式传输的音频应用(7)——ElevenLabs:高级智能语音技术

Gradio全解10——Streaming&#xff1a;流式传输的音频应用&#xff08;7&#xff09;——ElevenLabs&#xff1a;高级智能语音技术10.7 ElevenLabs&#xff1a;高级智能语音技术10.7.1 核心功能与可用模型1. 核心功能与产品2. 三类语音模型10.7.2 文本转语音API1. 完整操作步骤…

【桃子同学笔记4】PCIE训练状态机(LTSSM)基础

首先&#xff0c;所谓LTSSM&#xff0c;即&#xff1a;Link Training and Status State Machine&#xff08;链路训练及状态机&#xff09; 下图为 LTSSM 的状态机及训练过程&#xff1a; LTSSM 包含 11 个顶层状态&#xff1a;Detect、Polling、Configuration、Recovery、L0、…

STM32传感器模块编程实践(十五)DIY语音对话控制+满溢检测智能垃圾桶模型

文章目录 一.概要二.实验模型原理1.硬件连接原理框图2.控制原理 三.实验模型控制流程四.语音控制垃圾桶模型程序五.实验效果视频六.小结 一.概要 以前介绍的智能垃圾桶模型都是通过超声波模块感知控制&#xff0c;这次介绍一款新的智能垃圾桶&#xff0c;直接使用语音交互模块…

[bat-cli] docs | 控制器

链接&#xff1a;https://github.com/sharkdp/bat 前文传送&#xff1a; 【探索Linux命令行】从基础指令到高级管道操作的介绍与实践【Linux命令行】从时间管理-&#xff1e;文件查找压缩的指令详解【Linux】1w详解如何实现一个简单的shell docs&#xff1a;bat bat 是一个*…

无线自动信道调整

通过信道调整功能&#xff0c;可以保证每个AP 能够分配到最优的信道&#xff0c;尽可能地 减少和避免相邻信道干扰&#xff0c;而且通过实时信道检测&#xff0c;使AP 实时避开雷达&#xff0c;微波炉等干扰源。 动态信道调整能够实现通信的持续进行&#xff0c;为网络的可靠传…