功能说明:

使用最大化骨骼的时候需要添加动骨,但是对于不同的时装每个动骨组件要有不同的数据,因此希望将所有动骨的数据序列化存储到lua文件夹中,可读性好,使用xlua也易于解析,之后如果想要在原有参数上做调整,只需要将数据文件再导入或者直接修改lua文件中的某个参数即可;

InspectorUI扩展:

首先是写了一个InspectorUI的扩展,一个存储按钮和一个解析按钮;

    public override void OnInspectorGUI(){DrawButtons();base.OnInspectorGUI();}private void DrawButtons(){if (GUILayout.Button("Export LuaConfig")){Serialized();}if (GUILayout.Button("Import LuaConfig")){Parse();}}

存储到lua文件:

导出lua时可能会遇到各种报错,这里先提供一个枚举表示各种结果,然后写一个弹框接口来显示结果;

    public enum EExportRetType {success = 0,wrongGameObject = 1,noDBCom = 2,};private void ShowExportMessageBox(EExportRetType ret){switch (ret){case EExportRetType.success :EditorUtility.DisplayDialog("导出配置文件", "大吉大利,今晚吃鸡", "确定");break;case EExportRetType.wrongGameObject :EditorUtility.DisplayDialog("导出配置文件", "请选择Bip001或head_guadian骨骼进行导出", "确定");break;case EExportRetType.noDBCom :EditorUtility.DisplayDialog("导出配置文件", "当前导出骨骼下没有动骨组件", "确定");break;}}

 要存储骨骼下所有的动骨数据,我们需要拿到所有的动骨组件,然后拿到每一个动骨数据;这里我们使用动骨的游戏对象名作为key,每个key对应它所有的数据;接下来问题就变成了如何序列化一个动骨组件的数据,先简化思考一下:如果仅仅是存储一个int数据呢,这应该是很简单的,拿到动骨组件,拿到这个数据,用这个字段名作为key,然后拿到它的值存储起来即可,其它基本数据类型也是如此,而一些自定义的类其实就是这些数据的组合,包括Unity定义的一些类,在DynamicBone里有一个AnimationCurve,它的组成粒度都是一些基本数据类型,明白这一点就可以对各种数据做一些分别处理,这里我使用一个FormatToLua来重载存储各种数据类型;

需要注意的一些语法细节点:

  • bool转换成string时,true会变为True,所以这里要使用ToLower();
  • 枚举值使用int进行存储,转换时使用(int)强转即可;
  • 在string.Format中,{}属于特殊字符,如果要打印,需要使用"{{}}",也就是要double;
    private string FormatToLua(string key, string val){return string.Format("        {0} = '{1}',\n", key, val);}private string FormatToLua(string key, bool val){return string.Format("        {0} = {1},\n", key, val.ToString().ToLower());}private string FormatToLua(string key, float val){return string.Format("        {0} = {1},\n", key, val);}private string FormatToLua(string key, int val){return string.Format("        {0} = {1},\n", key, val);}private string FormatToLua(string key, Vector3 val){return FormatToLua(key, val.x, val.y, val.z);}private string FormatToLua(string key, params string[] val){var valueStr = "{";for(int i = 0; i < val.Length; i++){valueStr += string.Format("'{0}'", val[i]);if (i != val.Length - 1){valueStr += ", ";}else{valueStr += "}";}}return string.Format("        {0} = {1},\n", key, valueStr);}private string FormatToLua(string key, params float[] val){var valueStr = "{";for(int i = 0; i < val.Length; i++){valueStr += val[i];if (i != val.Length - 1){valueStr += ", ";}else{valueStr += "}";}}return string.Format("        {0} = {1},\n", key, valueStr);}private string FormatToLua(string key, AnimationCurve curve){var valueStr = "{\n";var keys = curve.keys;for(int i = 0; i < keys.Length; i++){valueStr += FormatToLua((i + 1).ToString(), keys[i]);}valueStr += "        }";return string.Format("        {0} = {1},\n", key, valueStr);}private string FormatToLua(string key, Keyframe kf){var valueStr = "{\n";var fmtStr = "        ";valueStr += fmtStr + FormatToLua("time", kf.time);valueStr += fmtStr + FormatToLua("value", kf.value);valueStr += fmtStr + FormatToLua("inTangent", kf.inTangent);valueStr += fmtStr + FormatToLua("inWeight", kf.inWeight);valueStr += fmtStr + FormatToLua("outTangent", kf.outTangent);valueStr += fmtStr + FormatToLua("outWeight", kf.outWeight);valueStr += fmtStr + FormatToLua("weightedMode", (int)kf.weightedMode);valueStr += fmtStr + "    }";return string.Format("            [{0}] = {1},\n", key, valueStr);}

然后就可以将组件的数据存储到一个字符串内了,如下所示,本来想用反射,但是反射得到的对象值都是object类型;然后写入到lua文件中即可;

    private string SerializedSingleCom(DynamicBone dbCom){string content = "";content += string.Format("    ['{0}'] = {{\n", dbCom.name);// foreach(var fieldInfo in typeDB.GetFields(BindingFlags.Public | BindingFlags.Instance)){//     string name = fieldInfo.Name;//     var value = fieldInfo.GetValue(dbCom);//     var fieldTypeStr = fieldInfo.FieldType.ToString();//     Type fieldType = fieldInfo.FieldType.AsType();//     if (!CheckIsInBlackList(fieldTypeStr) && value != null){//         sw.WriteLine(FormatToLua(name, value as fieldType));//     }// }content += FormatToLua("lodToggle", dbCom.lodToggle);content += FormatToLua("m_Root", dbCom.m_Root.name);content += FormatToLua("m_UpdateRate", dbCom.m_UpdateRate);content += FormatToLua("m_Damping", dbCom.m_Damping);content += FormatToLua("m_Elasticity", dbCom.m_Elasticity);content += FormatToLua("m_Stiffness", dbCom.m_Stiffness);content += FormatToLua("m_Inert", dbCom.m_Inert);content += FormatToLua("m_Radius", dbCom.m_Radius);content += FormatToLua("m_EndLength", dbCom.m_EndLength);content += FormatToLua("m_DistantDisable", dbCom.m_DistantDisable);content += FormatToLua("m_DistanceToObject", dbCom.m_DistanceToObject);content += FormatToLua("m_FreezeAxis", (int)dbCom.m_FreezeAxis);content += FormatToLua("m_EndOffset", dbCom.m_EndOffset);content += FormatToLua("m_Gravity", dbCom.m_Gravity);content += FormatToLua("m_Force", dbCom.m_Force);content += FormatToLua("m_DampingDistrib", dbCom.m_DampingDistrib);content += FormatToLua("m_ElasticityDistrib", dbCom.m_ElasticityDistrib);content += FormatToLua("m_StiffnessDistrib", dbCom.m_StiffnessDistrib);content += FormatToLua("m_InertDistrib", dbCom.m_InertDistrib);content += FormatToLua("m_RadiusDistrib", dbCom.m_RadiusDistrib);content += "    },\n";return content;}

从lua文件中恢复动骨组件数据:

恢复动骨数据很简单,只要解决一个问题,如何从lua文件中取出想要的数据;这里只讲述这个问题的思路,首先将lua文件加载出来,得到一个LuaTable,然后使用这个table来取数据;得到table以后,我们可以使用table.GetKeys(),它返回一个迭代器,我们可以得到所有的key-val,拿到每个组件的数据,

        LuaEnv luaEnv = new LuaEnv();luaEnv.AddLoader(CustomLoader);string luaPath = string.Format("{0}.lua", path);object[] objs = luaEnv.DoString("return require('Common.ActorBone.4000002_DB')");LuaTable table = objs[0] as LuaTable;foreach (var item in table.GetKeys()){var tb = table.Get<LuaTable>(item);var ret = ParseSingleDBCom(item.ToString(), tb);if (!ret){return;}}

在LuaTable类中提供了这样一个接口,用于拿到table中的数据,无论是数组段table还是hash段table都可以,我们可以一层层获取到所有数据,然后使用组件的实例化函数来完成所有的赋值操作:

        public TValue Get<TValue>(string key){TValue ret;Get(key, out ret);return ret;}tb.Get<float>(1)tb.Get<bool>("inTangent")tb.Get<LuaTable>(i)

 

完整代码如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ActorBoneSerialize : MonoBehaviour
{
}
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using XLua;
using LuaInterface;[SerializeField]
[CustomEditor(typeof(ActorBoneSerialize), true)]
public class ActorBoneSerializeEditor : Editor
{public enum EExportRetType {success = 0,wrongGameObject = 1,noDBCom = 2,};public enum EImportRetType {success = 0,wrongGameObject = 1,noCfg = 2,wrongCfg = 3,};private Type typeDB = typeof(DynamicBone);private string[] blackList = {"System.Collections.Generic.List`1[DynamicBoneCollider]","System.Collections.Generic.List`1[Transform]",};public override void OnInspectorGUI(){DrawButtons();base.OnInspectorGUI();}private void DrawButtons(){if (GUILayout.Button("Export LuaConfig")){Serialized();}if (GUILayout.Button("Import LuaConfig")){Parse();}}public void Serialized(){var go = (target as ActorBoneSerialize).gameObject;if(go.name != "Bip001" && go.name != "head_guadian"){ShowExportMessageBox(EExportRetType.wrongGameObject);return;}SerializedObjectDB(go);}private void SerializedObjectDB(GameObject go){var dbArray = go.GetComponentsInChildren<DynamicBone>();if(dbArray.Length == 0){ShowExportMessageBox(EExportRetType.noDBCom);}var fileName = go.transform.parent.name + "_DB";string pathF = string.Format("{0}/{1}.lua", Application.dataPath + "/Lua/Common/ActorBone", fileName);var content = "";content += "return {\n";for(int i = 0; i < dbArray.Length; i++){var dbCom = dbArray[i];content += SerializedSingleCom(dbCom);}content += "}";WriteAsset(pathF, content, false);ShowExportMessageBox(EExportRetType.success);}// 序列化单个组件的所有属性private string SerializedSingleCom(DynamicBone dbCom){string content = "";content += string.Format("    ['{0}'] = {{\n", dbCom.name);// foreach(var fieldInfo in typeDB.GetFields(BindingFlags.Public | BindingFlags.Instance)){//     string name = fieldInfo.Name;//     var value = fieldInfo.GetValue(dbCom);//     var fieldTypeStr = fieldInfo.FieldType.ToString();//     Type fieldType = fieldInfo.FieldType.AsType();//     if (!CheckIsInBlackList(fieldTypeStr) && value != null){//         sw.WriteLine(FormatToLua(name, value as fieldType));//     }// }content += FormatToLua("lodToggle", dbCom.lodToggle);content += FormatToLua("m_Root", dbCom.m_Root.name);content += FormatToLua("m_UpdateRate", dbCom.m_UpdateRate);content += FormatToLua("m_Damping", dbCom.m_Damping);content += FormatToLua("m_Elasticity", dbCom.m_Elasticity);content += FormatToLua("m_Stiffness", dbCom.m_Stiffness);content += FormatToLua("m_Inert", dbCom.m_Inert);content += FormatToLua("m_Radius", dbCom.m_Radius);content += FormatToLua("m_EndLength", dbCom.m_EndLength);content += FormatToLua("m_DistantDisable", dbCom.m_DistantDisable);content += FormatToLua("m_DistanceToObject", dbCom.m_DistanceToObject);content += FormatToLua("m_FreezeAxis", (int)dbCom.m_FreezeAxis);content += FormatToLua("m_EndOffset", dbCom.m_EndOffset);content += FormatToLua("m_Gravity", dbCom.m_Gravity);content += FormatToLua("m_Force", dbCom.m_Force);content += FormatToLua("m_DampingDistrib", dbCom.m_DampingDistrib);content += FormatToLua("m_ElasticityDistrib", dbCom.m_ElasticityDistrib);content += FormatToLua("m_StiffnessDistrib", dbCom.m_StiffnessDistrib);content += FormatToLua("m_InertDistrib", dbCom.m_InertDistrib);content += FormatToLua("m_RadiusDistrib", dbCom.m_RadiusDistrib);content += "    },\n";return content;}private void ShowExportMessageBox(EExportRetType ret){switch (ret){case EExportRetType.success :EditorUtility.DisplayDialog("导出配置文件", "大吉大利,今晚吃鸡", "确定");break;case EExportRetType.wrongGameObject :EditorUtility.DisplayDialog("导出配置文件", "请选择Bip001或head_guadian骨骼进行导出", "确定");break;case EExportRetType.noDBCom :EditorUtility.DisplayDialog("导出配置文件", "当前导出骨骼下没有动骨组件", "确定");break;}}private string FormatToLua(string key, string val){return string.Format("        {0} = '{1}',\n", key, val);}private string FormatToLua(string key, bool val){return string.Format("        {0} = {1},\n", key, val.ToString().ToLower());}private string FormatToLua(string key, float val){return string.Format("        {0} = {1},\n", key, val);}private string FormatToLua(string key, int val){return string.Format("        {0} = {1},\n", key, val);}private string FormatToLua(string key, Vector3 val){return FormatToLua(key, val.x, val.y, val.z);}private string FormatToLua(string key, params string[] val){var valueStr = "{";for(int i = 0; i < val.Length; i++){valueStr += string.Format("'{0}'", val[i]);if (i != val.Length - 1){valueStr += ", ";}else{valueStr += "}";}}return string.Format("        {0} = {1},\n", key, valueStr);}private string FormatToLua(string key, params float[] val){var valueStr = "{";for(int i = 0; i < val.Length; i++){valueStr += val[i];if (i != val.Length - 1){valueStr += ", ";}else{valueStr += "}";}}return string.Format("        {0} = {1},\n", key, valueStr);}private string FormatToLua(string key, AnimationCurve curve){var valueStr = "{\n";var keys = curve.keys;for(int i = 0; i < keys.Length; i++){valueStr += FormatToLua((i + 1).ToString(), keys[i]);}valueStr += "        }";return string.Format("        {0} = {1},\n", key, valueStr);}private string FormatToLua(string key, Keyframe kf){var valueStr = "{\n";var fmtStr = "        ";valueStr += fmtStr + FormatToLua("time", kf.time);valueStr += fmtStr + FormatToLua("value", kf.value);valueStr += fmtStr + FormatToLua("inTangent", kf.inTangent);valueStr += fmtStr + FormatToLua("inWeight", kf.inWeight);valueStr += fmtStr + FormatToLua("outTangent", kf.outTangent);valueStr += fmtStr + FormatToLua("outWeight", kf.outWeight);valueStr += fmtStr + FormatToLua("weightedMode", (int)kf.weightedMode);valueStr += fmtStr + "    }";return string.Format("            [{0}] = {1},\n", key, valueStr);}private bool CheckIsInBlackList(string str){for(int i = 0; i < blackList.Length; i++){if (blackList[i] == str){return true;}}return false;}// 导入lua配置 *****************************************************************public void Parse(){var go = (target as ActorBoneSerialize).gameObject;if(go.name != "Bip001" && go.name != "head_guadian"){ShowImportMessageBox(EImportRetType.wrongGameObject);return;}var fileName = go.transform.parent.name + "_DB";string pathF = string.Format("{0}/{1}.lua", Application.dataPath + "/Lua/Common/ActorBone", fileName);string relativePath = "Common/ActorBone/" + fileName;if (!File.Exists(pathF)){ShowImportMessageBox(EImportRetType.noCfg);return;}ParseLuaCfg(relativePath);ShowImportMessageBox(EImportRetType.success);}private void ParseLuaCfg(string path){LuaEnv luaEnv = new LuaEnv();luaEnv.AddLoader(CustomLoader);string luaPath = string.Format("{0}.lua", path);object[] objs = luaEnv.DoString("return require('Common.ActorBone.4000002_DB')");LuaTable table = objs[0] as LuaTable;foreach (var item in table.GetKeys()){var tb = table.Get<object>(item);var ret = ParseSingleDBCom(item.ToString(), tb as LuaTable);if (!ret){return;}}}private bool ParseSingleDBCom(string boneName, LuaTable tb){var go = GameObject.Find(boneName);if (go == null){ShowImportMessageBox(EImportRetType.wrongCfg);return false;}var dbCom = go.GetComponent<DynamicBone>();if (dbCom == null){dbCom = go.AddComponent<DynamicBone>();}// tb.Get<string, bool>("lodToggle", out dbCom.lodToggle);dbCom.lodToggle = tb.Get<bool>("lodToggle");dbCom.m_Root = GetTransformByName(tb.Get<string>("m_RootName"));dbCom.m_UpdateRate = tb.Get<float>("m_UpdateRate");dbCom.m_Damping = tb.Get<float>("m_Damping");dbCom.m_Elasticity = tb.Get<float>("m_Elasticity");dbCom.m_Stiffness = tb.Get<float>("m_Stiffness");dbCom.m_Inert = tb.Get<float>("m_Inert");dbCom.m_Radius = tb.Get<float>("m_Radius");dbCom.m_EndLength = tb.Get<float>("m_EndLength");dbCom.m_DistantDisable = tb.Get<bool>("m_DistantDisable");dbCom.m_FreezeAxis = (DynamicBone.FreezeAxis) tb.Get<int>("m_FreezeAxis");dbCom.m_EndOffset = GetVector3FromTable(tb.Get<LuaTable>("m_EndOffset"));dbCom.m_Gravity = GetVector3FromTable(tb.Get<LuaTable>("m_Gravity"));dbCom.m_Force = GetVector3FromTable(tb.Get<LuaTable>("m_Force"));dbCom.m_DampingDistrib = GetCurveFromTable(tb.Get<LuaTable>("m_DampingDistrib"));dbCom.m_ElasticityDistrib = GetCurveFromTable(tb.Get<LuaTable>("m_ElasticityDistrib"));dbCom.m_StiffnessDistrib = GetCurveFromTable(tb.Get<LuaTable>("m_StiffnessDistrib"));dbCom.m_InertDistrib = GetCurveFromTable(tb.Get<LuaTable>("m_InertDistrib"));dbCom.m_RadiusDistrib = GetCurveFromTable(tb.Get<LuaTable>("m_RadiusDistrib"));return true;}private Transform GetTransformByName(string name){var go = GameObject.Find(name);if (go == null){return null;}else{return go.transform;}}private Vector3 GetVector3FromTable(LuaTable tb){return new Vector3(tb.Get<float>(1), tb.Get<float>(2), tb.Get<float>(3));}private AnimationCurve GetCurveFromTable(LuaTable tb){if (tb.Length == 0){return null;}Keyframe[] keys = new Keyframe[tb.Length];for (int i = 1; i < tb.Length; i++){keys[i - 1] = GetKeyFrameFromTable(tb.Get<LuaTable>(i));}AnimationCurve curve = new AnimationCurve(keys);return curve;}private Keyframe GetKeyFrameFromTable(LuaTable tb){var kf = new Keyframe(tb.Get<float>("time"), tb.Get<float>("value"));kf.inTangent = tb.Get<float>("inTangent");kf.inWeight = tb.Get<float>("inWeight");kf.outTangent = tb.Get<float>("outTangent");kf.outWeight = tb.Get<float>("outWeight");kf.weightedMode = (WeightedMode) tb.Get<float>("weightedMode");return kf;}private void ShowImportMessageBox(EImportRetType ret){switch (ret){case EImportRetType.success :EditorUtility.DisplayDialog("导入配置文件", "导入成功", "确定");break;case EImportRetType.wrongGameObject :EditorUtility.DisplayDialog("导入配置文件", "请选择Bip001或head_guadian骨骼进行导入", "确定");break;case EImportRetType.noCfg :EditorUtility.DisplayDialog("导入配置文件", "缺少相应的lua配置文件", "确定");break;case EImportRetType.wrongCfg :EditorUtility.DisplayDialog("导入配置文件", "配置文件和骨骼不匹配", "确定");break;}}// 自定义loaderprivate byte[] CustomLoader(ref string fileName){return ResourceManager.Instance.LoadLua(fileName);}private string ReadLuaAsset(string resPath){string text = "";StreamReader streamReader = new StreamReader(resPath);text = streamReader.ReadToEnd();streamReader.Close();return text;}// 保存文件到指定位置private void WriteAsset(string desPath, string text, bool encoderShouldEmitUTF8Identifier = true){bool throwOnInvalidBytes = false;UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier, throwOnInvalidBytes);bool append = false;StreamWriter streamWriter = new StreamWriter(desPath, append, encoding);streamWriter.Write(text);streamWriter.Close();AssetDatabase.ImportAsset(desPath);}
}

 

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

相关文章

  1. POS机选择和使用

    POS使用前提:支付牌照和一清二清机 养卡之前我们要确认手上的pos机是否安全,其实有支付牌照的正规支付公司都是安全的。 **怎么知道一个支付公司是否有支付牌照呢?**可以去央行官网查询(中国人民银行 http://www.pbc.gov.cn/ ),进入官网后拉到最底部在左下“政务公开”找…...

    2024/4/11 21:30:29
  2. 《0day安全》堆溢出利用(下)——代码植入

    《0day2》堆溢出利用(下)——代码植入常用狙击目标(xp sp1前) 与栈溢出中的“地毯式轰炸”不同,堆溢出更加精准,往往直接狙击重要目标。精准是DWORD SHO OT 的优点,但“火力不足”有时也会限制堆溢出的利用,这样就需要选择最重要的目标用来“狙击”。 &emps;1.内存…...

    2024/4/11 21:30:28
  3. Scratch编程(十二)侦测模块

    侦测模块积木组里的所有的积木都是用来检测场景中某一参数的变化,通过参数变化来为下一步操作提供条件依据。具体分为:1、侦测运动积木组 2、侦测按键积木组 3、侦测基本参数积木组 4、其他积木组一、Scratch侦测运动积木组1、碰到鼠标指针:侦测角色碰到鼠标指针…...

    2024/4/10 11:20:10
  4. 我凭借这份pdf拿下了阿里巴巴、字节跳动、京东等大厂的offer

    】关于程序员,除了做项目来提高自身的技术之外,还有一种提升自己的专业技能就是:多!看!书!博主整理出一篇Java进阶架构师之路的核心知识,同时也是面试时面试官必问的知识点,篇章也是包括了很多知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微…...

    2024/4/10 11:20:09
  5. SpringBoot基础之@SpringBootApplication

    Spring的自动装配@SpringBootApplication一、@SpringBootConfig二、自定义starter三 、总结 一、@SpringBootConfig 随着Spring框架的流行,在web服务器端的开发,Spring几乎成了开发的标准。但是随着开发的业务越来越复杂,分布式微服务的出现。基于SpringBoot开发在web服务端…...

    2024/4/17 8:57:25
  6. pdf预览在vue项目中的使用兼容ie浏览器

    最近做项目有需求需要pdf在线预览并支持下载,而且还要兼容ie浏览器,之前又是使用过vue-pdf插件在chrome上没有问题但是在ie上不兼容。最后使用了pdf.Js这个原生库,虽然网上有许多使用教程但是还是踩了不少坑,所以在此记录下来。 一、下载pdf.js这个插件链接: https://pan.b…...

    2024/4/10 11:20:07
  7. python自动化测试实例—保险测试场景中的应用

    python自动化测试实例—保险测试场景中的应用 公司是做保险项目的测试,发现保险测试是一件非常繁琐的事情,特别是保费那块。 事情是这样的:要测一款重疾险,不同年龄段的人保费会不相同,有或是没有社保,保费不相同,还有各种附加险选择买或者是不买,最终保费也会不一样。…...

    2024/4/10 11:20:06
  8. 伪类选择器(重要)

    链接伪类选择器注意事项为了确保生效,请按照 LVHA 的循顺序声明 :link-:visited-:hover-:active。 记忆法:love hate 或者 lv 包包 hao 。 因为 a 链接在浏览器中具有默认样式,所以我们实际工作中都需要给链接单独指定样式下面是代码: 顺序声明 :link-:visited-:hover-…...

    2024/4/10 11:20:05
  9. is 与 == 的区别

    对象的三大特征: value (值), type (类型), id (地址) is 表示是否为同一个 == 表示是否相等 可以理解成 一个是比较value值,一个是比较id值 a = "abcder" b = "abcder" print(id(a)) #31253232 print(id(b)) #31253232 print(a == b) …...

    2024/4/16 18:14:39
  10. 利用libqrencode生成二维码

    关于二维码 Version 二维码一共有40个尺寸。官方叫版本Version。Version 1是21 x 21的矩阵,Version 2是 25 x 25的矩阵,Version 3是29的尺寸,每增加一个version,就会增加4的尺寸,公式是:(V-1)*4 + 21(V是版本号) 最高Version 40,(40-1)*4+21 = 177,所以最高是177 x 1…...

    2024/4/10 11:20:03
  11. C#学习-运算符重载(operator)

    运算符重载意义:使某些运算符具有新的功能重载的前提:方法必须是public和static注意:参数类型和返回值类型可以随意设置,但要合法可重载的运算符:算术运算符:全部,eg:+、-、*、/、++、--赋值运算符:全部不可关系运算符:全部,但必须要成对重载。eg:“<”要和“>…...

    2024/4/11 21:30:26
  12. pm2服务端部署支持ts的那些坑

    1.文件结构如下图pm2常用命令pm2 delete all //先停止所有的端口 pm2 delete $id //停止某个端口cd 到bin文件夹下,执行 pm2 start ../pm2.json pm2 log $id //打印端口信息pm2 flush //删除信息,否则日志是历史日志发现不支持ts-node,配置的时候加上,如果装了之后发…...

    2024/4/13 13:11:42
  13. 计算机原理--操作系统概览

    操作系统概览What&Why操作系统的基本功能操作系统相关概念 What&Why操作系统是管理计算机硬件和软件资源的计算机程序 管理配置内存、决定资源供需顺序、控制输入输出设备等 操作系统提供让用户和系统交互的操作界面 操作系统的种类是多种多样的,不局限于计算机 从手机…...

    2024/4/11 21:30:24
  14. JavaSE进阶——线程池、Lambda表达式

    第一章 等待唤醒机制 1.1 线程间通信 **概念:**多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。 比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个是生产,一个是消费,那么线程A与线程B之间就存在线…...

    2024/4/11 21:30:23
  15. java.sql.SQLException: Access denied for user ‘root‘@‘localhost‘ (using password: YES)

    java.sql.SQLException: Access denied for user ‘root’@‘192.168.1.105’ (using password: YES)一直报这个错误,正常应该检查权限和登录密码,然而我都检查过了还是报错 最后在实验中找到了解决问题的办法: spring:datasource:url: jdbc:mysql://192.168.1.105:3306/my…...

    2024/4/20 17:46:43
  16. AirtestIDE解决无法连接安卓模拟器的问题

    1.关闭手机助手类APP 2.确保设置中开发者选项里开启“允许USB调试”3.安装Yosemite.apk。该文件在\AirtestIDE\airtest\core\android\static\apks位置下4.在AirtestIDE的"远程连接设备"中,输入本机的IP和端口号,点击连接进行测试。如果连接成功会在"移动设备连…...

    2024/4/11 21:30:21
  17. saplink的安装和使用

    saplink 用于在不同的 SAP 系统之间传输开发物件和 DDIC 对象,它和其下一代产品 abapGit 都已经在 Github 上开源,如果是 Netweaver 702 之后的产品,建议使用 abapGit,之前的版本只能使用 saplink。saplink 存在较多 bug,项目已经没有开发者维护,如果不能驾驭 saplink,不…...

    2024/4/11 21:30:21
  18. 【C#学习日记】封装

    【C#学习日记】封装1. 综述2. 访问修饰符3. lazy实现的单例模式(附加)1. 综述 在面向对象程序设计方法论中,封装是为防止对实现细节的访问。抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。 2. 访问修饰符 public: 允许…...

    2024/4/11 21:30:20
  19. Docker入门到专精06-容器间通信与共享数据

    容器间Link单向通信 容器间的单向访问演示 分别启动两个容器 # --name 指定容器标识 docker run -d --name web tomcat # -it 进入交互模式+后台运行/bin/bash 防止容器退出 docker run -d --name database -it centos /bin/bash使用docker inspect 指令查询容器ip [root@local…...

    2024/4/11 21:30:18
  20. 抓取网页访客手机号原理

    网页抓取手机号...

    2024/4/11 21:30:17

最新文章

  1. OpenHarmony实战开发-搜索功能实现案例、如何使用includes方法对数据实现模糊查询

    介绍 本示例介绍使用includes方法对数据实现模糊查询 效果图预览 使用说明 点击首页搜索框跳转到搜索页面在搜索页面输入框中输入搜索的内容&#xff0c;下方列表自动根据搜索的内容进行筛选渲染点击筛选后的列表跳转到相应的页面跳转后会保存搜索历史&#xff0c;搜索历史使…...

    2024/4/20 20:39:08
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 分享一个Python爬虫入门实例(有源码,学习使用)

    一、爬虫基础知识 Python爬虫是一种使用Python编程语言实现的自动化获取网页数据的技术。它广泛应用于数据采集、数据分析、网络监测等领域。以下是对Python爬虫的详细介绍: 架构和组成:下载器:负责根据指定的URL下载网页内容,常用的库有Requests和urllib。解析器:用于解…...

    2024/4/19 7:49:37
  4. 多态--下

    文章目录 概念多态如何实现的指向谁调谁&#xff1f;例子分析 含有虚函数类的大小是多少&#xff1f;虚函数地址虚表地址多继承的子类的大小怎么计算&#xff1f;练习题虚函数和虚继承 概念 优先使用组合、而不是继承; 继承会破坏父类的封装、因为子类也可以调用到父类的函数;…...

    2024/4/16 22:07:08
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/4/19 19:02:10
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/4/20 15:00:23
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/4/19 11:33:34
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/4/19 11:52:08
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/4/20 9:42:32
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/4/20 7:01:14
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/4/19 11:52:49
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/4/19 18:52:15
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/4/19 23:08:02
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/4/20 0:22:23
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/4/19 23:04:54
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/4/20 1:12:38
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/4/20 19:58:29
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/4/19 19:50:16
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/4/20 1:43:00
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/4/20 13:55:02
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/4/19 23:35:17
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/4/19 10:00:05
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/4/20 6:45:17
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/4/20 3:28:04
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57