self.abc = nil [abc release]的区别

本文探讨了Objective-C中内存管理的两种关键方式:使用self.property=nil和直接调用[variable release]的区别。前者通过属性的setter方法实现,后者则是直接作用于实例变量。文章还讨论了这些方法对对象生命周期的影响,并提出了一种更安全的做法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

self.abc = nil 和[abc release]的本质区别是 前者使用property的点操作符,也就相当于调用了对应的set method,

和这句是一样的:[self setAbc: nil]; 而后者没有通过property,直接访问了成员变量,调用了它的release方法。

对于set method来说,用synthesize来让系统帮我们生成的set方法和如下的类似:

- (void)setAbc: (id)newAbc { if(abc != newAbc){ [abc release]; abc = [newAbc retain]; //是retain还是copy取决于你property声明时的attributes } }


补充: 对于一个全局变量,例如view1,在使用完后只是[view1 release]的话,view1是没有被完全释放的,

这时候view1的指针还有地址,是很危险的,所以得[view1 release]后再view1 = nil; 综合看起来的话,使用self.view1 = nil;是比较安全些 view1是retain对象

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
内容概要:本文研究了企业人工智能(AI)发展对低技能就业的影响,基于2012-2022年中国A股上市公司的数据,发现AI显著减少了低技能员工的数量。研究还揭示了数字化转型和人力资本投资在这一过程中起到中介作用,表明AI不仅直接替代低技能岗位,还通过提升数字化能力和技能需求间接影响就业。异质性分析显示,这些负面影响在非国有企业和非高科技企业中尤为明显。此外,文章通过Python代码展示了详细的复现步骤,包括数据预处理、基准回归、中介效应分析、异质性分析及可视化。 适用人群:对AI与劳动力市场关系感兴趣的学者、政策制定者以及从事相关研究的数据分析师。 使用场景及目标:①理解AI对企业低技能就业的具体影响;②分析数字化转型和人力资本投资的中介作用;③探讨不同企业类型(如国有企业与非国有企业、高科技与非高科技企业)在AI影响下的异质性表现;④通过代码实现复现实证研究结果,提供实证分析的方法论参考。 其他说明:本文不仅提供了理论分析,还通过详细的代码实现帮助读者理解具体的操作步骤。研究结果对于制定相关政策以应对AI带来的就业挑战具有重要参考价值,同时为后续研究提供了数据处理和模型构建的范例。文章最后讨论了研究的局限性和未来可能的研究方向,强调了治理结构和财务特征在AI转型中的重要作用。
我正在编辑【Emmylua】代码,遇到了 【LuaException: Projects/AAAShare/ShiYans/XiaHeMoYaWoGouFengBiShu/Mission/UI/UIXiShouPaiXun/ui_xishoupaixun.lua:609: attempt to index a nil value (field '?')】 ,请帮我检查并改正错误点。我的原始代码如下: 【----@class UIXiShouPaiXun:UIBaseView2 local UIXiShouPaiXun = BaseClass("UIXiShouPaiXun", UIBaseView2) function UIXiShouPaiXun:ShuffleArray(t) if not t then return {} end for i = #t, 2, -1 do local j = math.random(i) t[i], t[j] = t[j], t[i] end return t end -- 创建完调用 function UIXiShouPaiXun:LoadCallBack() -- override --UINameTable init start --上面的七个位置 ---@type UnityEngine.GameObject self.upimg1 = self:FindObj("upimg1") ---@type UnityEngine.GameObject self.upimg2 = self:FindObj("upimg2") ---@type UnityEngine.GameObject self.upimg3 = self:FindObj("upimg3") ---@type UnityEngine.GameObject self.upimg4 = self:FindObj("upimg4") ---@type UnityEngine.GameObject self.upimg5 = self:FindObj("upimg5") ---@type UnityEngine.GameObject self.upimg6 = self:FindObj("upimg6") ---@type UnityEngine.GameObject self.upimg7 = self:FindObj("upimg7") --下面的七个位置 ---@type UnityEngine.GameObject self.downimg1 = self:FindObj("downimg1") ---@type UnityEngine.GameObject self.downimg2 = self:FindObj("downimg2") ---@type UnityEngine.GameObject self.downimg3 = self:FindObj("downimg3") ---@type UnityEngine.GameObject self.downimg4 = self:FindObj("downimg4") ---@type UnityEngine.GameObject self.downimg5 = self:FindObj("downimg5") ---@type UnityEngine.GameObject self.downimg6 = self:FindObj("downimg6") ---@type UnityEngine.GameObject self.downimg7 = self:FindObj("downimg7") --七张图片 ---@type UnityEngine.GameObject self.xiShouImg1 = self:FindObj("xiShouImg1") ---@type UnityEngine.GameObject self.xiShouImg2 = self:FindObj("xiShouImg2") ---@type UnityEngine.GameObject self.xiShouImg3 = self:FindObj("xiShouImg3") ---@type UnityEngine.GameObject self.xiShouImg4 = self:FindObj("xiShouImg4") ---@type UnityEngine.GameObject self.xiShouImg5 = self:FindObj("xiShouImg5") ---@type UnityEngine.GameObject self.xiShouImg6 = self:FindObj("xiShouImg6") ---@type UnityEngine.GameObject self.xiShouImg7 = self:FindObj("xiShouImg7") --提交按钮 ---@type UnityEngine.GameObject self.btn_TiJiao = self:FindObj("btn_TiJiao") --正确答案显示按钮 ---@type UnityEngine.GameObject self.btn_zhengQue = self:FindObj("btn_zhengQue") ---@type UnityEngine.GameObject self.btn_NextStep = self:FindObj("btn_zhengQue") ---@type UnityEngine.Canvas self.CanvasUp = self:FindObj("CanvasUp"):GetComponent(typeof(CS.UnityEngine.Canvas)) ---@type UnityEngine.UI.Image self.CorrectMark = self:FindObj("CorrectMark"):GetComponent(typeof(CS.UnityEngine.UI.Image)) ---@type UnityEngine.UI.Image self.WrongMark = self:FindObj("WrongMark"):GetComponent(typeof(CS.UnityEngine.UI.Image)) ---@type UnityEngine.UI.Image self.righttMark1 = self:FindObj("righttMark1") ---@type UnityEngine.UI.Image self.righttMark2 = self:FindObj("righttMark2") ---@type UnityEngine.UI.Image self.righttMark3 = self:FindObj("righttMark3") ---@type UnityEngine.UI.Image self.righttMark4 = self:FindObj("righttMark4") ---@type UnityEngine.UI.Image self.righttMark5 = self:FindObj("righttMark5") ---@type UnityEngine.UI.Image self.righttMark6 = self:FindObj("righttMark6") ---@type UnityEngine.UI.Image self.righttMark7 = self:FindObj("righttMark7") --UINameTable init end --UIVariableTable init start --UIVariableTable init end --self.testGo1 = MissionManager.Instance:GetGameObject("XXX") ---@type UnityEngine.GameObject[] self.upPositions = { self.upimg1, self.upimg2, self.upimg3, self.upimg4, self.upimg5, self.upimg6, self.upimg7 } ---@type UnityEngine.GameObject[] self.downPositions = { self.downimg1, self.downimg2, self.downimg3, self.downimg4, self.downimg5, self.downimg6, self.downimg7 } ---@type UnityEngine.GameObject[] self.images = { self.xiShouImg1, self.xiShouImg2, self.xiShouImg3, self.xiShouImg4, self.xiShouImg5, self.xiShouImg6, self.xiShouImg7 } ---@type UnityEngine.UI.Image[] self.rightMarks = {} self.rightMarks[1] = self.righttMark1:GetComponent(typeof(CS.UnityEngine.UI.Image)) self.rightMarks[2] = self.righttMark2:GetComponent(typeof(CS.UnityEngine.UI.Image)) self.rightMarks[3] = self.righttMark3:GetComponent(typeof(CS.UnityEngine.UI.Image)) self.rightMarks[4] = self.righttMark4:GetComponent(typeof(CS.UnityEngine.UI.Image)) self.rightMarks[5] = self.righttMark5:GetComponent(typeof(CS.UnityEngine.UI.Image)) self.rightMarks[6] = self.righttMark6:GetComponent(typeof(CS.UnityEngine.UI.Image)) self.rightMarks[7] = self.righttMark7:GetComponent(typeof(CS.UnityEngine.UI.Image)) -- 初始化变量 self.imageStepMap = {} -- 图片到步骤的映射 self.positionToImage = {} -- 位置到图片的映射 self.imageToPosition = {} -- 图片到位置的映射 self.dragStartPositions = {} -- 拖拽起始位置 -- 设置图片的步骤映射 (1-7) for i, img in ipairs(self.images) do self.imageStepMap[img] = i end -- 初始化按钮状态 self:XianYin(self.btn_TiJiao, 0) self:XianYin(self.btn_zhengQue, 0) self:XianYin(self.btn_NextStep, 0) -- 初始化拖拽功能 self:InitDrag() -- 随机排列下方图片 self:ShuffleDownImages() -- 记录画布平面的Z位置 self.canvasZ = self.transform.position.z end -- 销毁前调用 function UIXiShouPaiXun:ReleaseCallBack() -- override --UINameTable delete start self.upimg1 = nil self.upimg2 = nil self.upimg3 = nil self.upimg4 = nil self.upimg5 = nil self.upimg6 = nil self.upimg7 = nil self.downimg1 = nil self.downimg2 = nil self.downimg3 = nil self.downimg4 = nil self.downimg5 = nil self.downimg6 = nil self.downimg7 = nil self.xiShouImg1 = nil self.xiShouImg2 = nil self.xiShouImg3 = nil self.xiShouImg4 = nil self.xiShouImg5 = nil self.xiShouImg6 = nil self.xiShouImg7 = nil self.btn_TiJiao = nil self.btn_zhengQue = nil self.CanvasUp = nil self.CorrectMark = nil self.WrongMark = nil self.righttMark1 = nil self.righttMark2 = nil self.righttMark3 = nil self.righttMark4 = nil self.righttMark5 = nil self.righttMark6 = nil self.righttMark7 = nil --UINameTable delete end --UIVariableTable delete start --UIVariableTable delete end self.upPositions = nil self.downPositions = nil self.images = nil self.rightMarks = nil self.imageStepMap = nil self.positionToImage = nil self.imageToPosition = nil self.dragStartPositions = nil self.canvasZ = nil end -- 打开后调用 function UIXiShouPaiXun:OpenCallBack() -- override --UIEventTable init start --点提交按钮的事件 self.onClickTiJiaoEvent = BindTool.Bind(self, self.OnClickTiJiao) self:ListenEvent("TiJiao", self.onClickTiJiaoEvent) --点正确答案按钮的事件 self.onClickZhengQueDaAnEvent = BindTool.Bind(self, self.OnClickZhengQueDaAn) self:ListenEvent("ZhengQueDaAn", self.onClickZhengQueDaAnEvent) --UIEventTable init end for _, masks in ipairs(self.rightMarks) do self:XianYin(masks.gameObject, 0) end end -- 关闭前调用 function UIXiShouPaiXun:CloseCallBack() -- override --UIEventTable delete start self:ClearEvent("TiJiao") self.onClickTiJiaoEvent = nil self:ClearEvent("ZhengQueDaAn") self.onClickZhengQueDaAnEvent = nil MissionManager.Instance:UnbindCustomBtn("下一步") --UIEventTable delete end end -- 刷新,使用Flush来触发此方法。 function UIXiShouPaiXun:OnFlush(param_list) -- override end -- 集中注册信息 function UIXiShouPaiXun:OnAddListener() -- override end -- 集中注销消息 function UIXiShouPaiXun:OnRemoveListener() -- override end ---@param key string ---@param saver Nirvana.MissionSystem.Save.Saver function UIXiShouPaiXun:Back(key, saver) --回退 --saver:ResetGameObject(key, self.testGo1) end ---@param key string ---@param saver Nirvana.MissionSystem.Save.Saver function UIXiShouPaiXun:Save(key, saver, ...) --保存 --saver:SaveGameObject(key, self.testGo1) end function UIXiShouPaiXun:SetParam(...) -- override -- 执行此方法的时候,请保证UI已经打开。 end function UIXiShouPaiXun:Start(...) -- override -- 开始 -- eg 1:直接完成 -- FWGlobalEventSystem:Fire(ShiYanEventType.OPERATE_OVER, self:GetName()) -- eg 2:申请交互 -- FWGlobalEventSystem:Fire(ShiYanEventType.TRY_INTERACT, self:GetName()) end function UIXiShouPaiXun:Imm(...) -- override -- 直接完成 FWGlobalEventSystem:Fire(ShiYanEventType.OPERATE_OVER, self:GetName()) end function UIXiShouPaiXun:Stop() -- override -- 停止 end function UIXiShouPaiXun:Continue() -- override -- eg 2:交互回调 --FWGlobalEventSystem:Fire(ShiYanEventType.OPERATE_OVER, self:GetName(),0,1) return false end function UIXiShouPaiXun:Guide(...) -- override return false end function UIXiShouPaiXun:XianYin(object, a) if object then -- 添加空值检查 object:SetActive(a == 1) end end function UIXiShouPaiXun:InitDrag() for _, img in ipairs(self.images) do self:AddDragEvents(img) end end function UIXiShouPaiXun:AddDragEvents(img) -- 获取或添加EventTrigger组件 local eventTrigger = img:GetComponent(typeof(CS.UnityEngine.EventSystems.EventTrigger)) if eventTrigger == nil then eventTrigger = img:AddComponent(typeof(CS.UnityEngine.EventSystems.EventTrigger)) else -- 清除现有事件 eventTrigger.triggers:Clear() end -- 开始拖拽事件 local beginEntry = CS.UnityEngine.EventSystems.EventTrigger.Entry() beginEntry.eventID = CS.UnityEngine.EventSystems.EventTriggerType.BeginDrag beginEntry.callback:AddListener(function() self:OnBeginDrag(img) end) eventTrigger.triggers:Add(beginEntry) -- 拖拽中事件 local dragEntry = CS.UnityEngine.EventSystems.EventTrigger.Entry() dragEntry.eventID = CS.UnityEngine.EventSystems.EventTriggerType.Drag dragEntry.callback:AddListener(function() self:OnDrag(img) end) eventTrigger.triggers:Add(dragEntry) -- 结束拖拽事件 local endEntry = CS.UnityEngine.EventSystems.EventTrigger.Entry() endEntry.eventID = CS.UnityEngine.EventSystems.EventTriggerType.EndDrag endEntry.callback:AddListener(function() self:OnEndDrag(img) end) eventTrigger.triggers:Add(endEntry) end -- 随机排列下方图片 function UIXiShouPaiXun:ShuffleDownImages() -- 重置所有映射关系 self.positionToImage = {} self.imageToPosition = {} local t = { 1, 2, 3, 4, 5, 6, 7 } -- 创建1-7的随机顺序 local randomOrder = self:ShuffleArray(t) -- 将图片放置到随机位置 for i, img in ipairs(self.images) do local pos = self.downPositions[randomOrder[i]] img.transform:SetParent(pos.transform) img.transform.localPosition = Vector3.zero img.transform:SetAsLastSibling() -- 确保显示在最上层 end end -- 开始拖拽处理 function UIXiShouPaiXun:OnBeginDrag(img) -- 记录当前拖拽的图片 self.draggingImage = img -- 记录拖拽前的父对象和位置 self.dragStartParent = img.transform.parent self.dragStartPosition = img.transform.localPosition -- 记录原始Z坐标 self.originalZ = img.transform.position.z -- 提升层级到最上层 img.transform:SetParent(self.transform) img.transform:SetAsLastSibling() end -- 拖拽中处理(跟随鼠标移动) function UIXiShouPaiXun:OnDrag(img) -- 获取鼠标位置 local mousePos = CS.UnityEngine.Input.mousePosition -- 获取画布相机 local camera = self.CanvasUp.worldCamera if camera == nil then camera = CS.UnityEngine.Camera.main end -- 确保有相机 if camera then -- 计算从相机到画布平面的距离 local distance = math.abs(camera.transform.position.z - self.canvasZ) -- 将屏幕坐标转换为世界坐标 local worldPos = camera:ScreenToWorldPoint( CS.UnityEngine.Vector3(mousePos.x, mousePos.y, distance) ) -- 保持原始Z坐标 worldPos = CS.UnityEngine.Vector3(worldPos.x, worldPos.y, self.originalZ) img.transform.position = worldPos end end -- 结束拖拽处理 function UIXiShouPaiXun:OnEndDrag(img) local hitPosition = nil -- 检查上方位置 for _, pos in ipairs(self.upPositions) do if self:IsPointInRect(pos, img) then hitPosition = pos break end end -- 检查下方位置 if not hitPosition then for _, pos in ipairs(self.downPositions) do if self:IsPointInRect(pos, img) then hitPosition = pos break end end end if hitPosition then self:PlaceImageToPosition(img, hitPosition) else -- 返回原始位置 img.transform:SetParent(self.dragStartParent) img.transform.localPosition = self.dragStartPosition end self.draggingImage = nil self:CheckAllPlaced() end function UIXiShouPaiXun:IsPointInRect(position, img) if not position or not img then return false end local rectTransform = position:GetComponent(typeof(CS.UnityEngine.RectTransform)) if not rectTransform then return false end local camera = self.CanvasUp.worldCamera if not camera then camera = CS.UnityEngine.Camera.main if not camera then -- 如果还是没有相机,返回false return false end end local imgRectTransform = img:GetComponent(typeof(CS.UnityEngine.RectTransform)) if not imgRectTransform then return false end local imgCenter = imgRectTransform.position local screenPos = camera:WorldToScreenPoint(imgCenter) -- 确保坐标有效(避免相机在物体后方的情况) if screenPos.z <= 0 then return false end local screenPos2 = CS.UnityEngine.Vector2(screenPos.x, screenPos.y) return CS.UnityEngine.RectTransformUtility.RectangleContainsScreenPoint( rectTransform, screenPos2, camera ) end -- 将图片放置到指定位置 function UIXiShouPaiXun:PlaceImageToPosition(img, position) -- 如果位置已有图片,交换位置 if self.positionToImage[position] then local otherImg = self.positionToImage[position] self:SwapImages(img, otherImg) else -- 更新映射关系 if self.imageToPosition[img] then self.positionToImage[self.imageToPosition[img]] = nil end self.positionToImage[position] = img self.imageToPosition[img] = position -- 设置新父对象和位置 img.transform:SetParent(position.transform) img.transform.localPosition = Vector3.zero -- 关键:设置为第一个子节点(底层) img.transform:SetAsFirstSibling() end end -- 交换两个图片的位置 function UIXiShouPaiXun:SwapImages(img1, img2) local pos1 = self.imageToPosition[img1] local pos2 = self.imageToPosition[img2] -- 更新映射关系 self.positionToImage[pos1] = img2 self.positionToImage[pos2] = img1 self.imageToPosition[img1] = pos2 self.imageToPosition[img2] = pos1 -- 交换父对象 img1.transform:SetParent(pos2.transform) img1.transform.localPosition = Vector3.zero img1.transform:SetAsFirstSibling() img2.transform:SetParent(pos1.transform) img2.transform.localPosition = Vector3.zero img2.transform:SetAsFirstSibling() end -- 检查所有上方位置是否都已放置图片 function UIXiShouPaiXun:CheckAllPlaced() local allPlaced = true -- 遍历所有上方位置 for _, pos in ipairs(self.upPositions) do if not self.positionToImage[pos] then allPlaced = false break end end -- 根据检查结果更新提交按钮状态 if self.btn_TiJiao then self.btn_TiJiao:SetActive(allPlaced) end end -- 点击提交按钮事件处理 function UIXiShouPaiXun:OnClickTiJiao() -- 禁用所有拖拽功能 for _, img in ipairs(self.images) do if img then local eventTrigger = img:GetComponent(typeof(CS.UnityEngine.EventSystems.EventTrigger)) if eventTrigger then eventTrigger.enabled = false end end end -- 检查每个位置是否正确 local allCorrect = true for i, pos in ipairs(self.upPositions) do local img = self.positionToImage[pos] if img and self.imageStepMap[img] == i then -- 位置正确,显示正确标记 self:ShowMark(img, true, i) else -- 位置错误,显示错误标记 self:ShowMark(img, false) allCorrect = false end end -- 更新按钮状态 if self.btn_TiJiao then self.btn_TiJiao:SetActive(false) end if allCorrect then -- 全部正确,显示下一步按钮 self:ShowNextStepButton() else -- 存在错误,显示正确答案按钮 if self.btn_zhengQue then self.btn_zhengQue:SetActive(true) end end end -- 在图片上显示正确/错误标记 function UIXiShouPaiXun:ShowMark(img, isCorrect, num) if not img then return end -- 根据正确性选择标记名称 self.rightMarks[num].sprite = isCorrect and self.CorrectMark.sprite or self.WrongMark.sprite if mark then self:XianYin(self.rightMarks[num].gameObject, 1) end end -- 隐藏所有图片上的标记 function UIXiShouPaiXun:HideAllMarks() for i, img in ipairs(self.images) do if img then ---- 查找正确标记 --local correctMark = img.transform:Find("CorrectMark") --if correctMark then -- correctMark.gameObject:SetActive(false) --end -- ---- 查找错误标记 --local wrongMark = img.transform:Find("WrongMark") --if wrongMark then -- wrongMark.gameObject:SetActive(false) --end self:XianYin(self.rightMarks[i].gameObject, 0) end end end -- 点击"正确答案"按钮事件处理 function UIXiShouPaiXun:OnClickZhengQueDaAn() -- 隐藏下方位置 for _, pos in ipairs(self.downPositions) do if pos then pos:SetActive(false) end end -- 隐藏所有标记 self:HideAllMarks() -- 将图片移动到正确位置 for i, pos in ipairs(self.upPositions) do if pos then local correctImg = self.images[i] -- 获取对应步骤的图片 if correctImg then correctImg.transform:SetParent(pos.transform) correctImg.transform.localPosition = Vector3.zero end end end ---- 更新按钮状态 --if self.btn_zhengQue then -- self.btn_zhengQue:SetActive(false) --end self:XianYin(self.btn_zhengQue.gameObject, 0) -- 显示下一步按钮 self:ShowNextStepButton() end function UIXiShouPaiXun:ShowNextStepButton() if self.btn_NextStep then self.btn_NextStep:SetActive(true) end MissionManager.Instance:BindCustomBtn("下一步", function() self:OnClickNextStep() end) end -- 点击下一步按钮事件处理 function UIXiShouPaiXun:OnClickNextStep() -- 触发完成事件 FWGlobalEventSystem:Fire(ShiYanEventType.OPERATE_OVER, self:GetName()) end return UIXiShouPaiXun;】
06-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值