ios报ASSERT FAILED ON LUA EXECUTE: key not found : <integer/real>的问题

本文探讨了TinyXML2解析器在遇到UTF8 BOM头时导致DictMaker类中的_state变量未初始化的问题,该问题在特定条件下会导致程序崩溃。文中提供了两种解决方法:一是移除文件的BOM头;二是初始化_state变量。

原文 :http://www.cocoachina.com/bbs/read.php?tid=282012


问题出现的原因


DictMaker有以下3个函数,用来处理tinyxml2的visit回调
void startElement(void *ctx, const char *name, const char **atts)
void endElement(void *ctx, const char *name)
void textHandler(void *ctx, const char *ch, int len)
当解析带有utf8 bom头的文件时,会首先调用textHandler这个函数,参数ch就是utf8的bom头:EF,BB,BF,参数len是3,
由于_state没有初始化,所以可能是任一个乱值。而如果恰好_state==SAX_STRING,就会报CCASSERT(!_curKey.empty(), "key not found : <integer/real>")这个错误。

在以往的win平台开发经验中,debug模式下,未初始化的变量为置0,release下未初始化的变量是乱值。但是在我测试的时候,android评上上,debug模式下,未初始化的变量是一个很大的乱值,但release模式下,出现过比较规则的4,5,9,11等等。。。
所以只要在解析带有utf8 bom头的文件时,并且恰好又_state==5,也就是_state==SAX_STRING时,就会报这个错误,并且是偶然发的。

如果解析的文件是没有bom头的话,就不会先执行textHandler,所以就没问题。




解决方案有2种

1.用工具去掉所有plist文件的bom头

2.CCFileUtils.cpp里面的DictMaker类,有一个变量 _state,这个变量没有初始化,在构造函数里将其初始化成SAX_NONE。

你提供的 HTML 是一个 `<select>` 下拉框元素,结构如下: ```html <select name="colvalue" id="14581081518097" onchange="javascript:colrule(this)" style="width:auto"> <option value="">-请选择-</option> <option value="10913">南宁市</option> <option value="1268814">崇左市</option> ... </select> ``` 你想使用 **“JS 直接赋值 + 触发事件”** 的方式来设置选中项(比如选择“南宁市”),并确保 `onchange="javascript:colrule(this)"` 被正确触发。 --- ### ✅ 正确做法:通过 JavaScript 设置 `value` 并手动触发 `change` 事件 Selenium 默认的 `select.select_by_value()` 方法是可靠的,但有时页面 JS 框架或自定义逻辑对事件监听很敏感,必须用 JS 才能完整触发所有行为。 下面是 **最稳定、推荐的 Python Selenium 实现方式**: --- ```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待 select 元素出现并可操作 wait = WebDriverWait(driver, 10) select_element = wait.until(EC.presence_of_element_located((By.NAME, "colvalue"))) # 使用 JavaScript 设置 value 并触发 change 事件 driver.execute_script(""" var select = arguments[0]; var value = '10913'; // 想要选中的 value,例如 南宁市 // 查找匹配 value 的 option 并设置 selected for (var i = 0; i < select.options.length; i++) { if (select.options[i].value === value) { select.options[i].selected = true; select.value = value; break; } } // 创建并触发 change 事件(冒泡,确保监听器能捕获) var event = new Event('change', { bubbles: true }); select.dispatchEvent(event); console.log('✅ 已选中 value=' + value + ', 并触发 change 事件'); """, select_element) print("✅ 下拉框已通过 JS 成功设置为‘南宁市’,且 colrule(this) 应已被调用") ``` --- ### ✅ 解释:为什么这么做? | 步骤 | 目的 | |------|------| | `select.value = value` 和 `option.selected = true` | 确保 DOM 状态更新 | | `new Event('change', { bubbles: true })` | 手动创建事件,因为直接赋值不会自动触发 | | `dispatchEvent(event)` | 触发绑定的 `onchange` 回调函数 `colrule(this)` | | `{ bubbles: true }` | 保证事件能被父级监听器捕获(兼容 jQuery 或框架) | > ⚠️ 如果你不触发 `change` 事件,`colrule(this)` 函数将 **不会执行**,可能导致后续联动逻辑(如二级下拉)不生效! --- ### ✅ 验证是否设置成功 你可以添加验证代码: ```python # 获取当前选中的文本和值 selected_value = driver.execute_script("return arguments[0].value;", select_element) selected_text = driver.execute_script( "return arguments[0].options[arguments[0].selectedIndex].text;", select_element ) print(f"当前选中值: {selected_value}, 文本: {selected_text}") assert selected_value == "10913" assert selected_text == "南宁市" print("✅ 验证通过:已成功选中‘南宁市’") ``` --- ### ✅ 替代方法(使用 Select 类) 如果你不需要绕过检测,也可以使用 Selenium 内置的 `Select` 类: ```python from selenium.webdriver.support.ui import Select select = Select(select_element) select.select_by_value("10913") # 自动触发 change(大多数情况下) ``` 但注意:某些 SPA 或 JS 框架会忽略原生 `select_by_value` 触发的事件,所以 **JS 方法更可靠**。 --- ### ✅ 通用封装函数(推荐复用) ```python def set_select_value(driver, locator, target_value): """通过 JS 设置 select 的值并触发 change 事件""" element = driver.find_element(*locator) driver.execute_script(""" var sel = arguments[0]; var val = arguments[1]; for (var i = 0; i < sel.options.length; i++) { if (sel.options[i].value === val) { sel.options[i].selected = true; sel.value = val; break; } } sel.dispatchEvent(new Event('change', {bubbles: true})); """, element, target_value) print(f"✅ 已设置下拉框为 value={target_value}") # 调用示例 set_select_value(driver, (By.NAME, "colvalue"), "1268814") # 选择 崇左市 ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值