UE5 C++委托内存泄漏全解析:从BindRaw到BindUObject的避坑指南
1. 项目概述为什么UE5 C委托是开发者的“双刃剑”在UE5的C开发世界里委托Delegate绝对是一个让人又爱又恨的存在。爱它是因为它提供了极其灵活和强大的事件驱动与回调机制是实现模块解耦、响应式编程的利器恨它则是稍有不慎它就会变成内存泄漏和程序崩溃的“定时炸弹”。我见过太多项目功能跑得飞起但运行一段时间后内存占用就悄悄飙升最后卡死或闪退一查十有八九是委托绑定没处理好。尤其是从BindRaw到BindUObject再到BindLambda每一种绑定方式背后都藏着不同的生命周期管理和内存所有权陷阱。新手开发者往往只关注功能是否实现而忽略了这些绑定操作在引擎底层是如何“记账”的等到问题爆发时排查起来又如同大海捞针。这篇指南就是把我自己以及身边同事踩过的坑、总结出的经验系统地梳理出来。我们不只讲“怎么用”更要深挖“为什么这么用”以及“用错了会怎样”目标是让你在UE5 C中驾驭委托时既能享受其便利又能彻底绕开那些恼人的内存泄漏深坑。2. 核心概念理解委托的生命周期与所有权在深入避坑之前我们必须建立起一个核心认知在UE5中委托不仅仅是一个函数指针的容器它更是一个与UE对象系统UObject和智能指针如TSharedPtr,TWeakPtr深度集成的系统。错误使用委托导致的内存泄漏本质上是对对象生命周期管理的不当。2.1 委托绑定的几种核心方式及其内存语义UE5的委托系统主要提供了以下几种绑定方式每一种都对应着不同的内存管理策略BindUObject: 这是最常用、也是最安全的方式之一。它绑定到一个UObject派生类实例的成员函数。其安全性来源于UE的垃圾回收Garbage Collection, GC系统。当一个UObject被标记为PendingKill即将被GC回收时所有通过BindUObject绑定到它的委托都会自动失效后续调用该委托是安全的通常什么也不做或返回默认值从而避免了悬挂指针。BindRaw: 它绑定到一个“原生”rawC对象指针的成员函数或者一个静态/全局函数。这是最危险的方式因为它完全绕过了UE的GC系统。委托持有的是原始指针它不知道目标对象是否还“活着”。如果对象被删除delete而委托未被解绑那么委托内部就持有了一个“悬挂指针”Dangling Pointer再次调用必然导致程序崩溃。更隐蔽的是如果对象是UObject但用BindRaw绑定即使GC回收了对象委托也不会知道隐患依旧。BindSP (BindShared) / BindWeak: 这对组合用于绑定到由TSharedPtr强引用或TWeakPtr弱引用管理的对象。BindSP要求传入一个TSharedPtr委托会内部持有一个强引用从而延长对象的生命周期——这可能导致循环引用对象永远无法释放。BindWeak则传入TWeakPtr委托内部持有弱引用不会阻止对象销毁但在调用前需要检查弱引用是否有效否则调用会失败。BindLambda: 用于绑定一个Lambda表达式非常灵活。Lambda可以捕获上下文变量。这里的关键是捕获方式按值捕获[]或[var]还是按引用捕获[]。按引用捕获外部变量时如果变量先于委托失效同样会产生悬挂引用。此外如果Lambda捕获了一个UObject指针但没有通过BindUObject的路径其生命周期同样不受GC保护。BindStatic: 绑定静态函数或全局函数。这本身是内存安全的因为函数地址是永久的。但需要注意静态函数内部如果访问了已销毁的全局或静态对象也会有问题。理解这些绑定方式的本质区别是避免内存泄漏的第一步。它们不是可以随意互换的语法糖而是代表了不同的“契约”和风险。2.2 UE5对象系统UObject与垃圾回收GC的联动这是BindUObject安全性的根源。UE的GC系统会跟踪所有UObject的引用关系。当一个UObject不再被任何其他UObject或游戏逻辑引用时它会被标记并在合适的GC周期被清理。BindUObject在绑定时委托系统会以某种方式通常是通过一个弱引用系统注册到该UObject。当GC准备销毁该对象时会通知所有相关的委托系统“这个对象要没了请清理与之相关的绑定”。于是委托内部的目标指针会被置空或标记为无效。关键心得BindUObject的安全边界仅限于UE的GC系统。如果你手动delete了一个UObject这本身是错误操作GC系统无从知晓BindUObject绑定的委托同样会失效并可能引发崩溃。因此对于UObject永远应该让GC来管理其生命周期。3. 从BindRaw到BindUObject典型内存泄漏场景深度剖析让我们通过几个具体的代码场景来看看内存泄漏是如何悄然发生的。3.1 场景一在Actor的Tick中BindRaw到临时对象这是新手最常见的错误模式之一。// MyActor.h DECLARE_DELEGATE_OneParam(FMyDelegate, int32); // MyActor.cpp void AMyActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); // 错误示范每次Tick都创建一个新的处理器并绑定 FMyDataProcessor* Processor new FMyDataProcessor(); MyDelegate.BindRaw(Processor, FMyDataProcessor::HandleData); // 触发委托 MyDelegate.ExecuteIfBound(42); // 问题Processor指针没有被删除委托绑定也没有解除。 // 下一次Tick又会new一个新的Processor旧的就彻底泄漏了。 }问题分析内存泄漏Memory Leaknew FMyDataProcessor()在堆上分配了内存但没有任何地方调用delete。这个指针在Tick函数结束后就丢失了分配的内存无法回收。委托持有悬挂指针即使我们后来补上了delete Processor;但MyDelegate内部仍然持有这个已被释放的指针。下次调用ExecuteIfBound时程序会试图访问已释放的内存导致未定义行为通常是崩溃。正确做法如果Processor需要持续存在将其作为Actor的成员变量FMyDataProcessor ProcessorInstance;在Actor构造时初始化在析构时自动清理。委托使用BindRaw绑定到ProcessorInstance因为成员变量的生命周期与Actor一致。如果Processor是临时性的使用智能指针管理其生命周期并对应地使用BindSP或BindWeak。最佳实践如果逻辑允许重构设计让FMyDataProcessor继承自UObject然后使用BindUObject。这样生命周期就交给GC省心又安全。3.2 场景二Lambda捕获中的循环引用与UObject陷阱Lambda非常方便但也容易埋坑。// Widget类中 void UMyWidget::SetupButton() { AMyPlayerController* PC GetOwningPlayer(); // 获取一个UObject指针 ConfirmButton-OnClicked.AddLambda([this, PC]() - void { // 捕获了this(UMyWidget*)和PC(AMyPlayerController*) if (this PC) // 这种检查对于UObject是无效的UObject应用IsValid() { this-DoSomething(); PC-ServerConfirmAction(); } }); }问题分析UObject有效性检查错误对于UObject指针不能直接用if (ptr)检查。因为UE的GC在销毁对象后并不会立即将内存清零指针可能非空但指向一个已失效对象。必须使用if (IsValid(ptr))。潜在的悬挂指针如果UMyWidget或AMyPlayerController在Lambda被调用前就被销毁例如Widget被从父级移除并GC那么Lambda中捕获的this和PC就是悬挂指针。调用this-DoSomething()会导致崩溃。循环引用风险如果使用智能指针如果this或PC是用TSharedPtr包装的Lambda按值捕获TSharedPtr会导致引用计数增加。如果委托本身被一个由this拥有的对象所持有就会形成循环引用两者都无法释放。正确做法void UMyWidget::SetupButton() { // 对于UObject在Lambda中应使用弱引用或直接让委托系统管理 AMyPlayerController* PC GetOwningPlayer(); // 方法1使用BindUObject如果目标是UObject成员函数 // 这里不适合因为Lambda里不完全是成员函数调用。 // 方法2在Lambda内使用弱引用或有效性检查 TWeakObjectPtrUMyWidget WeakThis(this); TWeakObjectPtrAMyPlayerController WeakPC(PC); ConfirmButton-OnClicked.AddLambda([WeakThis, WeakPC]() - void { UMyWidget* StrongThis WeakThis.Get(); AMyPlayerController* StrongPC WeakPC.Get(); if (IsValid(StrongThis) IsValid(StrongPC)) { StrongThis-DoSomething(); StrongPC-ServerConfirmAction(); } // 如果对象已失效Lambda安静地什么都不做这是安全的行为。 }); // 方法3确保委托在对象销毁前被清除。通常在Widget的析构函数或NativeDestruct中 // ConfirmButton-OnClicked.Clear(); }核心技巧对于Lambda中需要捕获的UObject指针养成使用TWeakObjectPtr的习惯。TWeakObjectPtr是UE为UObject提供的安全弱引用它会与GC系统协同工作在对象失效后能正确返回nullptr。3.3 场景三BindSP导致的循环引用死锁当你的对象不是UObject而是用TSharedPtr管理时BindSP可能带来循环引用。class FMyResource : public TSharedFromThisFMyResource { public: void Initialize() { // 假设有一个全局的事件分发器 GlobalEventDispatcher.OnResourceNeeded.BindSP(this-AsShared(), FMyResource::HandleEvent); } void HandleEvent() { /* ... */ } private: // ... 其他成员 }; TSharedPtrFMyResource Resource MakeSharedFMyResource(); Resource-Initialize(); // 当Resource超出作用域引用计数不会归零问题分析GlobalEventDispatcher内部持有了一个对FMyResource的强引用TSharedPtr。而FMyResource对象本身可能以某种方式直接或间接引用或持有GlobalEventDispatcher或者GlobalEventDispatcher的生命周期是永久的。这就形成了一个引用环A引用BB引用A两者的引用计数都无法降到0内存永远无法释放。正确做法优先使用BindWeak如果回调函数在对象不存在时可以被安全跳过总是使用BindWeak。GlobalEventDispatcher.OnResourceNeeded.BindWeak(this-AsShared(), FMyResource::HandleEvent);在GlobalEventDispatcher触发事件时内部会尝试将弱引用提升为强引用。如果对象已销毁提升失败委托调用会被忽略。手动管理生命周期在FMyResource的析构函数中显式地解绑委托。FMyResource::~FMyResource() { GlobalEventDispatcher.OnResourceNeeded.Unbind(); }这需要你能够访问到委托实例并持有它的引用有时在复杂系统中难以保证。重新审视设计思考是否真的需要双向引用。能否改用观察者模式、消息总线等更解耦的方式4. 系统性避坑策略与最佳实践知道了坑在哪里我们更需要一套系统性的方法来避免它们。4.1 绑定方式选择决策树面对一个回调需求你可以遵循以下决策流程来选择绑定方式目标对象是UObject吗是-首选BindUObject。让GC为你管理生命周期这是最安全省心的方式。否- 进入下一步。目标对象由智能指针TSharedPtr管理吗是-首选BindWeak。除非你能百分百确定不存在循环引用否则永远不要使用BindSP。BindWeak在对象存活时能正常工作对象销毁后自动失效完美避免泄漏和崩溃。否- 进入下一步。目标是静态函数、全局函数或生命周期与调用者完全一致的对象吗是- 可以使用BindRaw或BindStatic。但需确保“生命周期完全一致”例如绑定到另一个生命周期更长或同为栈对象的成员函数。否-重新设计你的对象生命周期管理。考虑将其改为UObject或用智能指针管理。不要强行使用BindRaw。需要使用Lambda吗是- 极度小心捕获列表。捕获UObject用TWeakObjectPtr。捕获TSharedPtr考虑按值捕获TWeakPtr。避免捕获this原始指针除非你能保证委托生命周期短于当前对象。优先捕获AsWeak()或使用弱引用。对于简单值类型按值捕获是安全的。4.2 对象销毁时的委托清理清单无论使用哪种绑定方式在对象销毁时主动清理其绑定的所有委托是一个极好的习惯。对于UObject在BeginDestroy()或EndPlay()对于Actor中清理。void UMyComponent::BeginDestroy() { // 清理所有绑定的委托 SomeDelegate.Unbind(); AnotherDelegate.Clear(); // 对于多播委托用Clear SomeEventDispatcher.Unbind(this); Super::BeginDestroy(); }对于非UObject类在析构函数中清理。FMyNonUObjectClass::~FMyNonUObjectClass() { // 清理委托 MyDelegate.Unbind(); }4.3 使用TWeakPtr和TWeakObjectPtr进行安全访问这是打破循环引用和避免悬挂指针的“银弹”。TWeakObjectPtrUMyClass用于安全地引用UObject。在访问前调用.Get()并配合IsValid()检查。TWeakPtrFMyNonUObjectClass用于安全地引用由TSharedPtr管理的对象。在访问前调用.Pin()获取一个临时的TSharedPtr如果返回的TSharedPtr有效则对象存活。在Lambda捕获、类成员变量存储不确定生命周期的引用时应优先考虑弱引用。5. 高级话题动态多播委托与资源释放单播委托相对简单多播委托DECLARE_MULTICAST_DELEGATE的管理则更需要细心因为它可以添加多个回调。5.1 多播委托的添加与移除添加委托使用Add系列函数AddUObject,AddRaw,AddSP,AddWeak,AddLambda。移除则需要一个“委托句柄”FDelegateHandle。// 声明一个多播委托 DECLARE_MULTICAST_DELEGATE_OneParam(FMyMulticastDelegate, int32); // 在类中 FMyMulticastDelegate OnSomethingHappened; FDelegateHandle MyDelegateHandle; void UMyClass::RegisterCallback() { // 添加绑定并保存句柄 MyDelegateHandle OnSomethingHappened.AddUObject(this, UMyClass::CallbackFunc); } void UMyClass::CallbackFunc(int32 Param) { // ... } void UMyClass::UnregisterCallback() { // 使用句柄精确移除 OnSomethingHappened.Remove(MyDelegateHandle); // 或者移除所有该对象绑定的委托更粗暴 // OnSomethingHappened.RemoveAll(this); }关键点务必在对象销毁前BeginDestroy或析构函数调用Remove或RemoveAll否则多播委托内部仍持有对已销毁对象的引用对于AddRaw是危险指针对于AddUObject虽然安全但会产生无效调用。5.2 委托作为成员变量的设计模式如果一个类对外提供委托通常将其声明为public。但更好的做法是提供订阅/取消订阅的接口以便在内部统一管理。class FMyService { public: // 返回一个句柄方便调用者取消订阅 FDelegateHandle SubscribeToEvent(const FMyDelegate Delegate) { return OnInternalEvent.Add(Delegate); } void UnsubscribeFromEvent(FDelegateHandle Handle) { OnInternalEvent.Remove(Handle); } private: DECLARE_MULTICAST_DELEGATE_OneParam(FMyDelegate, const FData); FMyDelegate OnInternalEvent; };这种模式将委托的实现细节隐藏起来提供了更清晰、更安全的生命周期管理接口。6. 调试与排查内存泄漏实战尽管遵循了最佳实践复杂的项目中仍可能出现内存泄漏。UE5提供了一些工具来帮你定位问题。6.1 使用Unreal Insights和内存分析工具Unreal Insights在开发配置下运行游戏使用stat memory命令或通过Insights捕获内存数据。关注Delegate相关的内存分配是否异常增长。虽然不能直接定位到具体泄漏点但可以告诉你是否存在委托相关的泄漏趋势。Visual Studio / JetBrains Rider 的内存分析器对于非UObject的泄漏可以使用这些IDE自带的内存分析工具。运行程序在疑似泄漏点前后抓取内存快照对比差异查看哪些FDelegate或相关对象没有被释放。6.2 代码审查与静态分析很多泄漏问题可以通过代码审查发现。重点关注所有BindRaw调用审视目标对象的生命周期。所有Lambda检查其捕获列表。所有Add了委托的地方是否在对应对象销毁时有Remove或Clear。在类的析构函数或BeginDestroy中打印日志确认对象按预期销毁。6.3 自定义委托追踪用于复杂调试在开发阶段可以创建一个简单的追踪系统来监控委托绑定。// 仅在开发版本启用 #if !UE_BUILD_SHIPPING #define TRACK_DELEGATE_BIND(Object, DelegateName) \ UE_LOG(LogTemp, Verbose, TEXT(Delegate Bound: %s to %s), \ TEXT(DelegateName), \ *GetNameSafe(Object)) #define TRACK_DELEGATE_UNBIND(Object, DelegateName) \ UE_LOG(LogTemp, Verbose, TEXT(Delegate Unbound: %s from %s), \ TEXT(DelegateName), \ *GetNameSafe(Object)) #else #define TRACK_DELEGATE_BIND(Object, DelegateName) #define TRACK_DELEGATE_UNBIND(Object, DelegateName) #endif // 使用时 void UMyClass::BindSomeDelegate() { SomeDelegate.BindUObject(this, UMyClass::Handler); TRACK_DELEGATE_BIND(this, SomeDelegate); } void UMyClass::BeginDestroy() { SomeDelegate.Unbind(); TRACK_DELEGATE_UNBIND(this, SomeDelegate); Super::BeginDestroy(); }通过查看输出日志你可以清晰地看到委托绑定和解绑的时序帮助发现哪些对象绑定后没有解绑。7. 总结与最后的忠告UE5 C的委托系统是一把威力巨大的瑞士军刀但锋利的刀刃也容易伤到自己。避免内存泄漏的关键在于时刻保持对对象生命周期和内存所有权的清醒认识。黄金法则能BindUObject就绝不用BindRaw能用BindWeak就绝不用BindSP。Lambda准则捕获UObject用TWeakObjectPtr捕获智能指针用TWeakPtr仔细评估捕获变量的生命周期。清理习惯在对象销毁时像关闭文件句柄一样清理它绑定的所有委托。设计原则模块间通过委托通信时尽量让“服务提供方”持有委托“服务使用方”进行绑定和解除绑定并在析构时主动解除。最后内存泄漏的排查往往比修复更耗时。养成良好的编码习惯在写下每一行绑定代码时都多问一句“这个对象什么时候死我的委托什么时候失效”就能在项目初期避免绝大多数令人头疼的内存问题。记住安全的代码不是偶然写出来的而是通过理解和遵循规则刻意构建出来的。

相关新闻

路由器越贵网速越稳?错!很多高端路由器都藏着“隐性限速”

路由器越贵网速越稳?错!很多高端路由器都藏着“隐性限速”

很多人陷入一个消费误区:网络不好路由器太便宜。 于是几百上千的高端路由、WiFi6、WiFi7设备换了一台又一台,结果发现:测速依旧满速,日常使用照样卡顿、掉帧、加载慢。 这根本不是设备不行,而是绝大多数人不知道&#…

2026/10/12 13:24:32 阅读更多 →
鸿蒙NEXT原生IM开发:基于MobileIMSDK的ArkTS实践

鸿蒙NEXT原生IM开发:基于MobileIMSDK的ArkTS实践

1. 项目背景与核心价值MobileIMSDK作为一款轻量级的开源IM即时通讯框架,已经在Android和iOS平台上得到了广泛应用。随着鸿蒙NEXT操作系统的推出,开发者对于原生支持鸿蒙生态的IM解决方案需求日益增长。这个项目正是基于MobileIMSDK核心协议,使…

2026/10/12 13:24:34 阅读更多 →
JNCA论文投稿格式全解析:从LaTeX模板到避坑指南

JNCA论文投稿格式全解析:从LaTeX模板到避坑指南

1. 论文投稿前的核心认知:为什么JNCA的格式如此重要?在计算机科学,特别是网络与分布式计算这个圈子里混久了,你肯定听说过Journal of Network and Computer Applications(JNCA)。这本由Elsevier出版的期刊&…

2026/10/12 19:56:32 阅读更多 →

最新新闻

Java面试如何从“背八股”到“技术深度”?一线模拟面试复盘与追问链解析

Java面试如何从“背八股”到“技术深度”?一线模拟面试复盘与追问链解析

1. 面试官视角的一次模拟:为什么背题高分选手反而被刷有位程序员朋友备考了两个月,把网上能搜到的Java面试题背得滚瓜烂熟,结果在一场模拟面试里连前面十分钟都没撑过。他描述某个项目的技术方案时,堆了一串名词,却说不…

2026/10/13 14:02:53 阅读更多 →
智能体权限安全实战:AI拥有操作能力后,如何守住权限边界?

智能体权限安全实战:AI拥有操作能力后,如何守住权限边界?

最近在做一个Agent项目时,权限配置把我折腾得不轻。模型的对话能力早就不是瓶颈了,真正让人夜里睡不着的是:当AI拿着工具去操作真实系统时,你怎么保证它只做该做的事?这周把一个跨平台的智能体接进内部工单系统试跑&am…

2026/10/13 14:02:53 阅读更多 →
AI落地场景验证的五大基础设施:算力、数据、模型、平台与场景

AI落地场景验证的五大基础设施:算力、数据、模型、平台与场景

最近一年我接触了不少AI落地项目,一个特别明显的感受是:大家终于不再纠结“大模型能不能做这件事”,而是开始纠结“在我们这个场景里,它能不能稳定、可控、划算地用起来”。这两句话之间隔着的那段路,就是场景验证。标…

2026/10/13 14:02:53 阅读更多 →
从HTML网页到可查询知识图谱:规则抽取与可视化实战

从HTML网页到可查询知识图谱:规则抽取与可视化实战

简介:这是一套从非结构化文本自动构造知识图的端到端管道,名为 KnowledgeGraph_Builder,面向 NLP 爱好者、算法工程师及知识图谱研究者。项目借助 spaCy、Stanford CoreNLP、Huggingface Neural Coref 和句子转换器等工具,实现了命…

2026/10/13 14:02:53 阅读更多 →
从大厂面经切入Agent开发:用真实场景重构AI工程能力

从大厂面经切入Agent开发:用真实场景重构AI工程能力

1. 项目概述:这不是刷题,而是一场面向真实工程的Agent能力重构“从面经开始的agent开发学习”——这个标题乍看像程序员求职路上的临时抱佛脚,实则藏着一条被多数人忽略的隐性路径:面经不是终点,而是Agent开发最密集、…

2026/10/13 14:02:53 阅读更多 →
Logstash离线插件安装实战:依赖解析、打包与验证全流程

Logstash离线插件安装实战:依赖解析、打包与验证全流程

1. 为什么Logstash插件必须离线安装——一个被低估的生产环境现实Logstash作为ELK栈中承上启下的数据管道核心,其价值从来不在“能跑起来”,而在于“能在哪跑、怎么稳跑、出问题时能否快速恢复”。我见过太多团队在测试环境用bin/logstash-plugin instal…

2026/10/13 14:01:51 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →