cocos creator 小技巧 - 代码混淆之后,类名消失的问题
问题:编译之后,继承与component的类,可以通过cc.js.getClassName获取类名,但是自定义类的类名是没法获取的分析:1.查看源码,能通过cc.js.getClassName调用函数名,必须要经过js.setClassName 函数定义;//文件地址:engine/cocos2d/platform/js.js/*** Register the class by specified
问题:
编译之后,继承与component的类,可以通过cc.js.getClassName获取类名,但是自定义类的类名是没法获取的
分析:
1.查看源码,能通过cc.js.getClassName调用函数名,必须要经过js.setClassName 函数定义;
//文件地址:engine/cocos2d/platform/js.js
/**
* Register the class by specified name manually
* @method setClassName
* @param {String} className
* @param {Function} constructor
*/
js.setClassName = function (className, constructor) {
doSetClassName(className, constructor);
// auto set class id
if (!constructor.prototype.hasOwnProperty('__cid__')) {
var id = className || tempCIDGenerater.getNewId();
if (id) {
js._setClassId(id, constructor);
}
}
};
2.查找setClassName的使用
//文件地址:engine/cocos2d/core/platform
function CCClass (options) {
options = options || {};
var name = options.name;
var base = options.extends/* || CCObject*/;
var mixins = options.mixins;
// create constructor
var cls = define(name, base, mixins, options);
if (!name) {
name = cc.js.getClassName(cls);
}
...
}
function define (className, baseClass, mixins, options) {
var Component = cc.Component;
var frame = cc._RF.peek();
if (frame && js.isChildClassOf(baseClass, Component)) {
//发现只有继承Component的才会在这里赋值 frame.script
className = className || frame.script;
}
var cls = doDefine(className, baseClass, mixins, options);
if (frame) {
...
}
return cls;
}
function doDefine (className, baseClass, mixins, options) {
...
js.setClassName(className, fireClass);
return fireClass;
}
3.发现所有的ccclass 都会经过如上代码,
在define函数中,只有继承Component才会去 用frame.script赋值给className,
我们看看frame.script的来历
cc._RF = {
push: function (module, uuid, script) {
if (script === undefined) {
script = uuid;
uuid = '';
}
requiringFrames.push({
uuid: uuid,
script: script,
module: module,
exports: module.exports, // original exports
beh: null
});
},
pop: function () {
var frameInfo = requiringFrames.pop();
// check exports
var module = frameInfo.module;
var exports = module.exports;
if (exports === frameInfo.exports) {
for (var anyKey in exports) {
// exported
return;
}
// auto export component
module.exports = exports = frameInfo.cls;
}
},
peek: function () {
return requiringFrames[requiringFrames.length - 1];
}
};
上面是HelloWorld编译后的代码
我们可以发现,cc._RF先 push 进去了一个对象,然后再调用@class装饰器生成类,
再生成类的过程中会调用上面的 define 函数, 然后用 cc._RF.peek() 查看存入的对象,从而拿到类名
解题思路:
用装饰器,在构造类的过程中去获取类名,调用 cc.js.setClassName() 设置类名
解决办法:
//创建类的装饰器,使用和ccclass类似
function keepClassName(target){
let frameInfo = cc['_RF'].peek();
let script = frameInfo.script;
cc.js.setClassName(script, target);
}
//用法
@keepClassName
export class UserClass{
}
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐
所有评论(0)