news 2026/3/8 4:39:53

iOS 触摸事件完整传递链路:Hit-Test 全流程深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
iOS 触摸事件完整传递链路:Hit-Test 全流程深度解析

触摸事件概述

事件类型

┌─────────────────────────────────────────────────────────────────────┐ │ iOS 事件类型总览 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Touch Events │ │ Motion Events │ │ Remote Events │ │ │ │ 触摸事件 │ │ 运动事件 │ │ 远程控制事件 │ │ │ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │ │ │ • 手指触摸屏幕 │ │ • 摇一摇 │ │ • 耳机线控 │ │ │ │ • 多点触控 │ │ • 加速度计 │ │ • 蓝牙控制 │ │ │ │ • 3D Touch │ │ • 陀螺仪 │ │ • CarPlay │ │ │ │ • Apple Pencil │ │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ ┌─────────────────┐ │ │ │ Press Events │ iOS 9+ 物理按键事件 │ │ │ 按压事件 │ (Apple TV Remote, 游戏手柄等) │ │ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘

UITouch 生命周期

/* ═══════════════════════════════════════════════════════════════════ UITouch 状态流转 ═══════════════════════════════════════════════════════════════════ 手指按下 手指移动 手指抬起 │ │ │ ▼ ▼ ▼ ┌──────┐ 移动中 ┌──────┐ 移动结束 ┌──────┐ │ Began │ ─────────→│ Moved │ ──────────────→│ Ended │ └──────┘ └──────┘ └──────┘ │ │ │ │ │ │ │ 系统中断(如来电) │ │ │ │ │ │ │ ▼ │ │ │ ┌──────────┐ │ │ └───→│Cancelled │←────┘ │ └──────────┘ │ │ │ └────────────────────────────────────┘ 事件结束 */// MARK: - UITouch 核心属性extensionUITouch{/// 触摸阶段publicenumPhase:Int{casebegan// 手指触摸屏幕casemoved// 手指在屏幕上移动casestationary// 手指在屏幕上但没有移动caseended// 手指离开屏幕casecancelled// 系统取消触摸(如来电)@available(iOS13.4,*)caseregionEntered// 指针进入区域(iPadOS 光标)@available(iOS13.4,*)caseregionMoved// 指针在区域内移动@available(iOS13.4,*)caseregionExited// 指针离开区域}/// 触摸类型publicenumTouchType:Int{casedirect// 直接触摸(手指)caseindirect// 间接触摸(Apple TV Remote)casepencil// Apple Pencil@available(iOS13.4,*)caseindirectPointer// 间接指针(鼠标/触控板)}}// MARK: - UITouch 信息获取示例classTouchInfoView:UIView{overridefunctouchesBegan(_touches:Set<UITouch>,with event:UIEvent?){guardlettouch=touches.firstelse{return}// 基本信息letlocation=touch.location(in:self)// 在当前视图中的位置letpreviousLocation=touch.previousLocation(in:self)// 上一次位置lettimestamp=touch.timestamp// 时间戳lettapCount=touch.tapCount// 点击次数(双击等)letphase=touch.phase// 当前阶段lettype=touch.type// 触摸类型// 压力信息(3D Touch / Apple Pencil)letforce=touch.force// 当前压力letmaximumPossibleForce=touch.maximumPossibleForce// 最大压力letnormalizedForce=force/maximumPossibleForce// 归一化压力 0~1// Apple Pencil 专属iftouch.type==.pencil{letaltitudeAngle=touch.altitudeAngle// 倾斜角度(与屏幕平面)letazimuthAngle=touch.azimuthAngle(in:self)// 方位角letazimuthVector=touch.azimuthUnitVector(in:self)// 方位向量}// 触摸半径(估计)letmajorRadius=touch.majorRadius// 触摸区域半径letmajorRadiusTolerance=touch.majorRadiusTolerance// 容差print(""" 📍TouchInfo:Location:\(location)Phase:\(phase)TapCount:\(tapCount)Force:\(normalizedForce)""")}}

UIEvent 事件容器

/* ═══════════════════════════════════════════════════════════════════ UIEvent 结构 ═══════════════════════════════════════════════════════════════════ ┌─────────────────────────────────────────────────────────────────┐ │ UIEvent │ ├─────────────────────────────────────────────────────────────────┤ │ type: EventType // 事件类型 │ │ subtype: EventSubtype // 子类型 │ │ timestamp: TimeInterval // 时间戳 │ ├─────────────────────────────────────────────────────────────────┤ │ allTouches: Set<UITouch>? // 所有触摸点 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Touch 1 │ │ Touch 2 │ │ Touch 3 │ ...多点触控 │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ */// UIEvent 类型extensionUIEvent{publicenumEventType:Int{casetouches// 触摸事件casemotion// 运动事件caseremoteControl// 远程控制事件casepresses// 按压事件@available(iOS13.4,*)casescroll// 滚动事件@available(iOS13.4,*)casehover// 悬停事件casetransform// 变换事件}}// 获取特定视图上的触摸extensionUIEvent{functouches(forview:UIView)->Set<UITouch>?{returnallTouches?.filter{$0.view==view}}functouches(forwindow:UIWindow)->Set<UITouch>?{returnallTouches?.filter{$0.window==window}}functouches(forgestureRecognizer:UIGestureRecognizer)->Set<UITouch>?{returnallTouches?.filter{touchintouch.gestureRecognizers?.contains(gestureRecognizer)??false}}}

事件传递全流程图解

完整事件传递链路

═══════════════════════════════════════════════════════════════════════════ 触摸事件完整传递流程 ═══════════════════════════════════════════════════════════════════════════ ┌──────────────────────────────────────────────────────────────────────┐ │ 硬件层 │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 触摸屏幕硬件 │ │ │ │ 检测到手指触摸,生成触摸数据 │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ └────────────────────────────────│────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ IOKit 层 │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ IOHIDEvent(硬件事件) │ │ │ │ 封装触摸数据为 IOHIDEvent 事件 │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ └────────────────────────────────│────────────────────────────────────┘ │ │ Mach Port 传递 ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ SpringBoard 进程 │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 接收 IOHIDEvent,判断前台 App,通过 Mach Port 转发给 App 进程 │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ └────────────────────────────────│────────────────────────────────────┘ │ │ Mach Port 传递 ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ App 进程 │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Source1(Mach Port) │ │ │ │ RunLoop 的 Source1 接收到 Mach Port 消息 │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Source0(触发) │ │ │ │ Source1 触发 Source0,将事件封装为 UIEvent │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ UIApplication │ │ │ │ application.sendEvent(event) → 发送到 UIWindow │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ UIWindow │ │ │ │ 执行 Hit-Test 寻找最佳响应视图 │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────┴─────────────────────┐ │ │ │ Hit-Test 过程 │ │ │ │ │ │ │ │ ┌─────────────────────────────────┐ │ │ │ │ │ hitTest:withEvent: │ │ │ │ │ │ pointInside:withEvent: │ │ │ │ │ │ 从后向前遍历子视图 │ │ │ │ │ │ 递归查找最深层可响应视图 │ │ │ │ │ └─────────────────────────────────┘ │ │ │ │ │ │ │ └─────────────────────┬─────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 找到 Hit-Test View │ │ │ │ (最适合处理触摸的视图) │ │ │ └─────────────────────────────┬───────────────────────────────────┘ │ │ │ │ │ ┌───────────────────────┴───────────────────────┐ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ 手势识别器 │ ←─ 同时接收事件 ─→ │ 触摸方法 │ │ │ │ Gesture │ │ touches... │ │ │ │ Recognizers │ │ 方法 │ │ │ └──────┬───────┘ └──────┬───────┘ │ │ │ │ │ │ │ 手势识别成功 │ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ 响应者链传递 │ │ │ │ HitTestView → SuperView → ... → ViewController → Window │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘ ═══════════════════════════════════════════════════════════════════════════

时序图

═══════════════════════════════════════════════════════════════════════════ 事件传递时序图 ═══════════════════════════════════════════════════════════════════════════ 时间 → │ │ ┌─────────┐ ┌──────────┐ ┌────────┐ ┌────────┐ ┌─────┐ ┌─────────┐ │ │Hardware │ │SpringBoard│ │RunLoop │ │UIApp │ │UIWin│ │HitTestV │ │ └────┬────┘ └─────┬────┘ └───┬────┘ └───┬────┘ └──┬──┘ └────┬────┘ │ │ │ │ │ │ │ │ │ IOHIDEvent │ │ │ │ │ │ │───────────→│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Mach Msg │ │ │ │ │ │ │─────────→│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Source1 │ │ │ │ │ │ │─────────→│ │ │ │ │ │ │ │ │ │ │ │ │ │ UIEvent │ │ │ │ │ │ │←─────────│ │ │ │ │ │ │ │ │ │ │ │ │ │ sendEvent │ │ │ │ │ │──────────┼────────→│ │ │ │ │ │ │ │ │ │ │ │ │ │ hitTest │ │ │ │ │ │ │────────→│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 递归查找 │ │ │ │ │ │ │─────────→│ │ │ │ │ │ │ │ │ │ │ │ │ │ 返回View │ │ │ │ │ │ │←─────────│ │ │ │ │ │ │ │ │ │ │ │ │ HitView │ │ │ │ │ │ │←────────│ │ │ │ │ │ │ │ │ │ │ │ │ 分发 touches... │ │ │ │ │ │ │─────────┼─────────→│ │ │ │ │ │ │ │ ▼ │ │ │ │ │ │ ═══════════════════════════════════════════════════════════════════════════

Hit-Test 机制详解

Hit-Test 核心算法

// MARK: - Hit-Test 默认实现(伪代码)/* ═══════════════════════════════════════════════════════════════════ Hit-Test 算法流程 ═══════════════════════════════════════════════════════════════════ hitTest:withEvent: 方法流程: ┌─────────────────────────────────────────────────────────────┐ │ 1. 检查自身是否可以接收事件 │ │ • hidden == false │ │ • userInteractionEnabled == true │ │ • alpha > 0.01 │ └─────────────────────────┬───────────────────────────────────┘ │ ┌───────────────┴───────────────┐ │ 不满足条件 │ 满足条件 ▼ ▼ 返回 nil ┌─────────────────────┐ │ 2. 检查点是否在自身范围内 │ │ pointInside:withEvent │ └───────────┬─────────────┘ │ ┌───────────┴───────────┐ │ 不在范围内 │ 在范围内 ▼ ▼ 返回 nil ┌─────────────────┐ │ 3. 倒序遍历子视图 │ │ (后添加的先遍历) │ └────────┬────────┘ │ ┌────────▼────────┐ │ 4. 递归调用子视图的 │ │ hitTest 方法 │ └────────┬────────┘ │ ┌────────┴────────┐ │ 子视图返回非nil │ 全部返回nil ▼ ▼ 返回该子视图 返回自己 */extensionUIView{/// Hit-Test 默认实现(系统实现的等效代码)openoverridefunchitTest(_point:CGPoint,with event:UIEvent?)->UIView?{// 1. 检查是否可以接收事件guardisUserInteractionEnabled,!isHidden,alpha>0.01else{returnnil}// 2. 检查点是否在自身范围内guardpoint(inside:point,with:event)else{returnnil}// 3. 倒序遍历子视图(后添加的视图在上层,优先响应)forsubviewinsubviews.reversed(){// 坐标转换:将点从当前视图坐标系转换到子视图坐标系letconvertedPoint=subview.convert(point,from:self)// 4. 递归调用子视图的 hitTestiflethitView=subview.hitTest(convertedPoint,with:event){returnhitView}}// 5. 没有子视图响应,返回自己returnself}/// 判断点是否在视图范围内(默认实现)openoverridefuncpoint(inside point:CGPoint,with event:UIEvent?)->Bool{returnbounds.contains(point)}}

Hit-Test 可视化演示

// MARK: - Hit-Test 过程可视化/* ═══════════════════════════════════════════════════════════════════ Hit-Test 遍历示例 ═══════════════════════════════════════════════════════════════════ 视图层级: ┌─────────────────────────────────────────────────────────────────┐ │ Window │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ RootView │ │ │ │ ┌─────────────────────┐ ┌─────────────────────────────┐ │ │ │ │ │ ViewA │ │ ViewB │ │ │ │ │ │ (subviews[0]) │ │ (subviews[1]) │ │ │ │ │ │ │ │ ┌───────────┐ ┌─────────┐ │ │ │ │ │ │ │ │ │ ViewB1 │ │ ViewB2 │ │ │ │ │ │ │ │ │ │ [0] │ │ [1] │ │ │ │ │ │ │ │ │ │ │ │ ✕ │ │ │ │ │ │ │ │ │ │ │ │ 触摸点 │ │ │ │ │ │ │ │ │ └───────────┘ └─────────┘ │ │ │ │ │ └─────────────────────┘ └─────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ Hit-Test 遍历顺序(假设触摸点在 ViewB2 上): ① Window.hitTest │ ├─ 检查 Window: ✓ 可交互 ✓ 点在范围内 │ └─② RootView.hitTest(Window 唯一子视图) │ ├─ 检查 RootView: ✓ 可交互 ✓ 点在范围内 │ ├─ 倒序遍历子视图... │ ├─③ ViewB.hitTest (subviews[1],后添加,先遍历) │ │ │ ├─ 检查 ViewB: ✓ 可交互 ✓ 点在范围内 │ │ │ ├─ 倒序遍历子视图... │ │ │ ├─④ ViewB2.hitTest (subviews[1]) │ │ │ │ │ ├─ 检查 ViewB2: ✓ 可交互 ✓ 点在范围内 │ │ ├─ 无子视图 │ │ └─ 返回 ViewB2 ✓ ←─── 找到目标! │ │ │ └─ 返回 ViewB2(子视图找到结果,不再遍历 ViewB1) │ └─ 返回 ViewB2(子视图找到结果,不再遍历 ViewA) 最终结果:ViewB2 成为 Hit-Test View */

自定义 Hit-Test 实战

// MARK: - 扩大按钮点击区域classExpandedButton:UIButton{/// 扩展的点击区域(负值表示向外扩展)vartouchAreaInsets:UIEdgeInsets=UIEdgeInsets(top:-10,left:-10,bottom:-10,right:-10)overridefuncpoint(inside point:CGPoint,with event:UIEvent?)->Bool{// 扩大判定区域letexpandedBounds=bounds.inset(by:touchAreaInsets)returnexpandedBounds.contains(point)}}// 使用示例letbutton=ExpandedButton()button.touchAreaInsets=UIEdgeInsets(top:-20,left:-20,bottom:-20,right:-20)// 四周各扩大20pt// MARK: - 让子视图超出父视图部分也能响应classOverflowContainerView:UIView{overridefunchitTest(_point:CGPoint,with event:UIEvent?)->UIView?{// 先检查子视图(即使超出范围)forsubviewinsubviews.reversed(){letconvertedPoint=subview.convert(point,from:self)// 不使用 pointInside,直接让子视图判断iflethitView=subview.hitTest(convertedPoint,with:event){returnhitView}}// 子视图都没响应,再判断自身ifpoint(inside:point,with:event){returnself}returnnil}}/* 使用场景: ┌─────────────────────────────┐ │ ContainerView │ │ │ │ ┌─────────────────┐ │ │ │ PopupView ├─┼──┐ ← 弹出视图超出容器 │ │ │ │ │ │ └─────────────────┘ │ │ │ │ │ └─────────────────────────────┘ │ │ 触摸这里也能响应 ─┘ */// MARK: - 穿透视图(让事件传递到下层)classPassthroughView:UIView{/// 需要穿透的子视图类型varpassthroughViews:[UIView.Type]=[]overridefunchitTest(_point:CGPoint,with event:UIEvent?)->UIView?{lethitView=super.hitTest(point,with:event)// 如果点击到自身或指定类型的视图,返回 nil 让事件穿透ifhitView===self{returnnil}// 检查是否是需要穿透的视图类型iflethitView=hitView{forviewTypeinpassthroughViews{iftype(of:hitView)==viewType{returnnil}}}returnhitView}}/* 使用场景:遮罩层穿透 ┌─────────────────────────────────────┐ │ BottomView(可点击的按钮等) │ │ ┌─────────────────────────────┐ │ │ │ PassthroughView(半透明遮罩) │ │ ← 点击遮罩区域 │ │ ┌───────────────┐ │ │ 穿透到 BottomView │ │ │ 弹窗内容 │ │ │ │ │ │ (可点击) │ │ │ │ │ └───────────────┘ │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────┘ */// MARK: - 自定义点击区域形状(圆形按钮)classCircleButton:UIButton{overridefuncpoint(inside point:CGPoint,with event:UIEvent?)->Bool{// 计算圆心和半径letcenter=CGPoint(x:bounds.width/2,y:bounds.height/2)letradius=min(bounds.width,bounds.height)/2// 计算点到圆心的距离letdx=point.x-center.xletdy=point.y-center.yletdistance=sqrt(dx*dx+dy*dy)// 距离小于半径则在圆内returndistance<=radius}}// MARK: - 多区域响应(一个View内有多个可点击区域)classMultiTapAreaView:UIView{structTapArea{letrect:CGRectlethandler:()->Void}vartapAreas:[TapArea]=[]overridefunctouchesEnded(_touches:Set<UITouch>,with event:UIEvent?){guardlettouch=touches.firstelse{return}letlocation=touch.location(in:self)// 查找点击的区域forareaintapAreas{ifarea.rect.contains(location){area.handler()return}}}}

Hit-Test 特殊情况处理

// MARK: - ScrollView 内按钮延迟响应问题/* 问题:UIScrollView 默认 delaysContentTouches = true 会延迟 150ms 判断是滑动还是点击,导致按钮响应慢 */classFastResponseScrollView:UIScrollView{overrideinit(frame:CGRect){super.init(frame:frame)// 关闭延迟,让内容立即响应delaysContentTouches=false}requiredinit?(coder:NSCoder){super.init(coder:coder)delaysContentTouches=false}// 防止 ScrollView 取消按钮的触摸overridefunctouchesShouldCancel(inview:UIView)->Bool{// 如果是 UIControl(按钮等),不取消触摸ifviewisUIControl{returnfalse}returnsuper.touchesShouldCancel(in:view)}}// MARK: - TableView Cell 内按钮点击classCellWithButton:UITableViewCell{letactionButton=UIButton()overrideinit(style:UITableViewCell.CellStyle,reuseIdentifier:String?){super.init(style:style,reuseIdentifier:reuseIdentifier)contentView.addSubview(actionButton)// 重要:按钮添加到 contentView,而不是 cell 本身// 这样 TableView 的选择和按钮点击可以独立工作}requiredinit?(coder:NSCoder){fatalError("init(coder:) has not been implemented")}overridefunchitTest(_point:CGPoint,with event:UIEvent?)->UIView?{// 先检查按钮letbuttonPoint=actionButton.convert(point,from:self)ifactionButton.point(inside:buttonPoint,with:event){returnactionButton}// 其他区域走默认逻辑returnsuper.hitTest(point,with:event)}}// MARK: - 手势冲突解决classGestureConflictView:UIView{lettapGesture=UITapGestureRecognizer()letinnerButton=UIButton()overrideinit(frame:CGRect){super.init(frame:frame)addGestureRecognizer(tapGesture)addSubview(innerButton)// 解决方案1:让手势在按钮区域失效tapGesture.delegate=self}requiredinit?(coder:NSCoder){fatalError("init(coder:) has not been implemented")}}extensionGestureConflictView:UIGestureRecognizerDelegate{funcgestureRecognizer(_gestureRecognizer:UIGestureRecognizer,shouldReceive touch:UITouch)->Bool{// 如果触摸到按钮,手势不接收letlocation=touch.location(in:self)ifinnerButton.frame.contains(location){returnfalse}returntrue}}

响应者链(Responder Chain)

响应者链结构

═══════════════════════════════════════════════════════════════════════════ 响应者链结构 ═══════════════════════════════════════════════════════════════════════════ UIResponder 继承体系: ┌──────────────┐ │ UIResponder │ ← 抽象基类 └──────┬───────┘ │ ┌──────────────────────┼──────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌───────────────┐ ┌──────────────────┐ │ UIView │ │UIViewController│ │ UIApplication │ └──────┬──────┘ └───────────────┘ └──────────────────┘ │ ├─────────────────┬─────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ UIWindow │ │ UIControl │ │UIScrollView │ └─────────────┘ └──────┬──────┘ └─────────────┘ │ ┌────────────┼────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │UIButton │ │UISlider │ │UISwitch │ └─────────┘ └─────────┘ └─────────┘ 响应者链传递路径示例: ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────┐
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 17:06:27

Visual Studio中的 var 和 dynamic

目录 一、var 1.基础介绍 2.语法模板 二、dynamic 1.基础介绍 2.语法模板 三、两者关键区别--示例 四、核心特点对比 五、注意事项 var的注意事项 dynamic的注意事项 六、选择情况 一、var 1.基础介绍 var&#xff1a;隐式类型局部变量 定义&#xff1a;编译时由…

作者头像 李华
网站建设 2026/3/3 14:37:15

ONLYOFFICE 协作空间 3.6.1 发布:安全补丁与多项优化

我们很高兴地宣布 ONLYOFFICE 协作空间 3.6.1 正式发布。本次更新重点聚焦于安全漏洞修复和功能优化&#xff0c;在提升系统安全性的同时&#xff0c;进一步增强了 AI 智能体的使用体验。 关于 ONLYOFFICE 协作空间 ONLYOFFICE 协作空间是一款以 “房间”为核心概念的在线文档…

作者头像 李华
网站建设 2026/3/3 14:37:14

SPFA算法

在图论的世界里&#xff0c;“最短路径” 是个高频需求 —— 比如从家到公司的最优路线、网络中数据传输的最短延迟。我们知道 Dijkstra 算法很经典&#xff0c;但它怕负权边&#xff1b;Bellman-Ford 算法能处理负权边&#xff0c;却慢得让人着急。今天要讲的 SPFA 算法&#…

作者头像 李华
网站建设 2026/3/3 14:37:16

高频Jmeter软件测试面试题

近期&#xff0c;有很多粉丝在催更关于Jmeter的面试题&#xff0c;索性抽空整理了一波&#xff0c;以下是一些高频Jmeter面试题&#xff0c;拿走不谢~ 一、JMeter的工作原理 JMeter就像一群将请求发送到目标服务器的用户一样&#xff0c;它收集来自目标服务器的响应以及其他统…

作者头像 李华
网站建设 2026/3/5 13:31:56

aliexpress 逆向分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;部分python代码n231 cp.call(get231, …

作者头像 李华
网站建设 2026/3/6 18:18:09

腾讯滑块 collect分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;部分python代码pow_cfg data["dat…

作者头像 李华