发明内容
本申请实施例提供一种编程环境下私有方法的实现方法、调用方法及相应的装置,目的在于保证方法调用性能的前提下,实现编程环境下私有方法真正意义上的私有化。
本申请实施例采用下述技术方案:
第一方面,本申请提供一种编程环境下私有方法的实现方法,包括:
当第一私有方法带有类实例的指针时,在类中按照编程语言的静态方法声明所述第一私有方法;其中,所述第一私有方法的声明的参数包括所述第一私有方法的类实例的指针;
按照编程语言的函数实现方法实现所述私有方法。
优选地,本申请提供编程环境下私有方法的实现方法中,当所述第一私有方法的实现需要访问私有变量时,按照编程语言的函数实现方法实现所述私有方法,包括:
以实例变量的形式在代码文件中声明所述私有变量;
采用指针访问保护器实现所述第一私有方法;其中,所述指针访问保护器的参数包括所述第一私有方法的类实例的指针和包含有所述第一私有方法的函数逻辑的代码块。
优选地,本申请提供编程环境下私有方法的实现方法中,当所述第一私有方法的运行需要返回值时,所述方法还包括:
在所述指针访问保护器的外部声明返回变量,以便将所述第一私有方法的运行结果赋值给所述返回变量;其中,所述返回变量用于返回所述第一私有方法的运行结果。
优选地,本申请提供编程环境下私有方法的实现方法中,在类中按照编程语言的静态方法声明所述第一私有方法,包括:
在类中按照C语言的静态方法在代码文件中声明所述第一私有方法。
优选地,本申请提供编程环境下私有方法的实现方法中,在采用指针访问保护器实现所述第一私有方法之后,所述方法还包括:
在所述编程环境下调用所述第一私有方法。
优选地,本申请提供编程环境下私有方法的实现方法中,在所述编程环境下调用所述第一私有方法,包括:
采用函数类型转换器将所述第一私有方法转换为编程环境方法供调用;其中,所述函数类型转换器的参数包括所述第一私有方法的函数指针、所述第一私有方法的名称标识符和所述第一私有方法所属类的类型标识符。
优选地,本申请提供编程环境下私有方法的实现方法中,所述第一私有方法的函数指针的类型与所述第一私有方法所包含的参数的数量存在对应关系;
采用函数类型转换器将所述第一私有方法转换为编程环境方法供调用,包括:
当所述第一私有方法中的参数的数量超出预设数值时,将部分或全部所述参数合并为数据结构,以便以所述数据结构的形式进行参数的传递。
优选地,本申请提供编程环境下私有方法的实现方法中,所述预设数值取为2或3。
优选地,本申请提供编程环境下私有方法的实现方法中,所述方法还包括:
当第二私有方法不带有类实例的指针时,在类中按照编程语言的静态方法声明所述第二私有方法;
按照编程语言函数的实现方式实现所述第二私有方法。
优选地,本申请提供编程环境下私有方法的实现方法中,在按照编程语言函数的实现方式实现所述第二私有方法之后,所述方法还包括:
按照编程语言函数的调用方式调用所述第二私有方法。
第二方面,本申请提供一种编程环境下私有方法的调用方法,包括:
采用函数类型转换器将第一私有方法转换为编程环境方法供调用;其中,所述函数类型转换器的参数包括所述第一私有方法的函数指针、所述第一私有方法的名称标识符和所述第一私有方法所属类的类型标识符;
其中,所述第一私有方法根据第一方面所提供的方法实现。
优选地,本申请提供编程环境下私有方法的调用方法中,所述第一私有方法的函数指针的类型与所述第一私有方法所包含的参数的数量存在对应关系;
采用函数类型转换器将所述第一私有方法转换为编程环境方法供调用,包括:
当所述第一私有方法中的参数的数量超出预设数值时,将部分或全部所述参数合并为数据结构,以便以所述数据结构的形式进行参数的传递。
优选地,本申请提供编程环境下私有方法的调用方法中,所述预设数值取为2或3。
优选地,本申请提供编程环境下私有方法的调用方法中,所述方法还包括:
按照编程语言函数的调用方式调用第二私有方法;
其中,所述第二私有方法按照以下方式实现:
当所述第二私有方法不带有类实例的指针时,在类中按照编程语言的静态方法声明所述第二私有方法;
按照编程语言函数的实现方式实现所述第二私有方法。
第三方面,本申请还提供一种编程环境下私有方法的实现装置,包括:
第一声明模块,用于当第一私有方法带有类实例的指针时,在类中按照编程语言的静态方法声明所述第一私有方法;其中,所述第一私有方法的声明的参数包括所述第一私有方法的类实例的指针;
第一实现模块,用于当所述第一私有方法的实现需要访问私有变量时,采用指针访问保护器实现所述第一私有方法;其中,所述指针访问保护器的参数包括所述第一私有方法的类实例的指针和包含有所述第一私有方法的函数逻辑的代码块。
优选地,本申请提供编程环境下私有方法的实现装置中,所述装置还包括:
第二声明模块,用于当第二私有方法不带有类实例的指针时,在类中按照C语言的静态方法声明所述第二私有方法;
第二实现模块,用于按照编程语言函数的实现方式实现所述第二私有方法。
第四方面,本申请还提供一种编程环境下私有方法的调用装置,包括:
第一调用模块,用于采用函数类型转换器将第一私有方法转换为编程环境方法供调用;其中,所述函数类型转换器的参数包括所述第一私有方法的函数指针、所述第一私有方法的名称标识符和所述第一私有方法所属类的类型标识符;
其中,所述第一私有方法根据第一方面所提供的方法或者第三方面所提供的装置实现。
本申请实施例采用的上述至少一个技术方案能够达到以下有益效果:
本申请实施例给出的技术方案,在类中按照编程语言的静态方法声明私有方法,以C语言为例,这种方式利用C语言层面的函数作用域限制,使得该私有方法对外部文件不可见,即使子类继承时也不可见,从而确保C函数的代码块无法被程序其他部分访问。同时,采用静态方法声明,使得C函数的代码块随着类的定义被分配和装载,因此即使知道函数名称,该C函数也无法被类以外的方法或函数调用,从而实现了真正意义上的私有化。当上述私有方法带有类实例的指针时,将该私有方法的声明的参数取为上述类实例的指针,并当第一私有方法的实现需要访问私有变量时,还可进一步采用指针访问保护器实现该私有方法,从而可以防止空对象的调用、访问或直接操作指针时引起的死机现象,有利于保证上述私有方法的运行性能。
进一步地,在调用上述私有方法时,以Objective-C机制下的调用为例,采用函数类型转换器,通过取私有方法的函数指针的方式,将C函数的函数指针作为函数类型转换器的参数,将采用C函数实现的上述私有方法转换成Objective-C机制所需要的方法,从而能够在Objective-C机制下正常调用私有方法,保证了上述私有方法在Objective-C机制下的运行性能。
具体实施方式
为使本申请的目的、技术方案和优点更加清楚,下面将结合本申请具体实施例及相应的附图对本申请技术方案进行清楚、完整地描述。显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
鉴于Objective-C是非常典型的缺乏私有方法解决方案的编程环境,故以下各实施例以Objective-C机制下的私有方法的声明、实现、调用方法和装置为例,结合附图说明本申请所提供的技术方案。
第一方面,本申请提供了Objective-C机制下(一种编程环境的示例)私有方法的实现方法。
当拟实现的私有方法不带有类实例的指针时(以下可将这种私有方法具体化为第二私有方法),在类中按照C语言(一种编程语言的示例)的静态方法声明该私有方法即可,优选在代码文件(.m文件)中声明。例如,可采用以下语句声明一个私有方法:
NS_INLINE void SNSParseSingularData(SNSSingularModel*singularModel,NSString*json),其中:
NS_INLINE表示静态内联函数声明;
void表示无返回值;
SNSParseSingularData表示函数名称;
SNSSingularModel*singularModel表示函数参数;
NSString*json表示函数参数。
按照上述方式声明的私有方法,不带有类实例的指针,进而在实现上述第二私有方法(如上例中声明的私有方法SNSParseSingularData)时,按照C语言函数的实现方式实现即可。在调用上述第二私有方法时,也按照C语言函数的调用方式即可。采用这种方式声明和实现的第二私有方法,其实质是C函数,因此,可以利用C语言层面的函数作用域限制,使得该私有方法对外部文件不可见,即使子类继承时也不可见,从而确保该C函数的代码块无法被程序其他部分访问。同时,采用静态方法声明,使得该C函数的代码块随着类的定义被分配和装载,因此即使知道函数名称,该C函数也无法被类以外的方法或函数调用,从而实现了真正意义上的私有化。
上述方案能够解决Objective-C环境下能够直接使用C函数实现的部分私有方法的声明、实现和调用问题。然而,Objective-C在某些场景下不能直接使用C函数,如事件回调、通知处理、OC方法传递等情况下,由于私有方法需要用到类实例的上下文环境,私有方法中带有类实例的指针。因此,当私有方法带有类实例的指针时(以下将这种私有方法具体化为第一私有方法),可以参考图1所示的流程实现这种私有方法,具体包括以下步骤:
S101:在类中按照C语言的静态方法声明第一私有方法;其中,第一私有方法的声明的参数包括第一私有方法的类实例的指针;
例如,可以采用以下语句进行第一私有方法的声明,将第一私有方法的类实例的指针作为第一私有方法的声明的第一个参数:
NS_INLINE void SNSSetupFeedView(SNSFeedButton*selfObj),其中:
NS_INLINE表示静态内联函数声明;
void表示无返回值;
SNSSetupFeedView表示函数名称;
SNSFeedButton*selfObj表示该类实例的指针对象。
需要说明的是,私有方法的声明,优选声明在代码文件(.m文件)中。
S102:当第一私有方法的实现需要访问类的私有变量时,采用指针访问保护器实现第一私有方法;其中,指针访问保护器的参数包括第一私有方法的类实例的指针和包含有第一私有方法的函数逻辑的代码块。
可以理解到,当第一私有方法的实现不需要访问类的私有变量时,直接实现即可。
在执行步骤S102之前,可以采用如下语句进行指针访问保护器的定义:
void call_self_ivar(id selfObj,void(^block)()),其中:
void表示该block无返回值;
call_self_ivar表示定义的指针访问保护器;
id selfObj表示私有方法所在类的实例;
void(^block)()表示一个无返回值的block(函数逻辑的代码块)。
采用上述语句定义的指针访问保护器,可以防止由于空对象调用、访问或直接操作指针时引起的死机现象。
基于以上示例的对指针访问保护器的定义,在采用指针访问保护器实现第一私有方法时,将第一私有方法的类实例的指针作为指针访问保护器的第一个参数,将包含有第一私有方法的函数逻辑的代码块作为指针访问保护器的第二个参数。例如,在执行步骤S102时,可以采用如下代码示例实现第一私有方法:
其中:
call_self_ivar表示调用的指针访问保护器;
selfObj表示第一私有方法的类实例的指针;
^后{}内部的部分表示包含有第一私有方法的函数逻辑的代码块(block)。
在上述实现的第一私有方法中,_style、_operationType、_config、_feedView都是实例变量型(iVar型)的私有变量,通过call_self_ivar的保护,即使selfObj为空,也不会出现系统崩溃。
可以理解到,当第一私有方法的实现需要访问类的私有变量时,需要先对类的这些私有变量进行声明。优选以实例变量(iVAR变量)的形式在代码文件(.m文件)中声明私有变量,不对外暴露,则当第一私有方法的实现需要访问私有变量时,通过类实例的指针访问私有变量,例如上述代码中的“feedView.config=selfObj->_config”等。
除此之外,Objective-C类的属性变量优选声明在头文件(.h文件)中,对外暴露,并尽量避免声明到代码文件(.m文件)。在访问上述声明的私有变量时,与第一私有方法通过类实例的指针访问私有变量不同的在于,Objective-C中的非私有方法可以直接使用私有变量的名称访问私有变量。
当采用以上的方式声明和实现的第一私有方法的运行需要返回值时,可以在指针访问保护器的外部声明返回变量(例如_block变量),从而可以将第一私有方法的运行结果赋值给返回变量;其中,返回变量用于返回第一私有方法的运行结果。
以上给出了在Objective-C机制下声明和实现私有方法的多种实施例。对于第二私有方法(如前所述的不带有类实例的指针的私有方法),可以直接采用标准C函数的调用方式使用。对于第一私有方法,可以执行步骤S103,在Objective-C机制下进行调用,参见图2所示。
更具体地,步骤S103在Objective-C机制下调用第一私有方法,可以具体包括,参见图3所示:
S1031:采用函数类型转换器将第一私有方法转换为OC方法供调用;其中,函数类型转换器的参数包括第一私有方法的函数指针、第一私有方法的名称标识符和第一私有方法所属类的类型标识符。
在具体实施时,可以将函数类型转换器(又可称为selector转换器)的第一个参数设定为第一私有方法的函数指针,函数类型转换器的第二个参数设定为第一私有方法的名称标识符,函数类型转换器的第三个参数设定为第一私有方法所属类的类型标识符。例如,可采用以下语句实现函数类型转换器:
SEL ASConvertFunctionToSelector(SelectorFunction*sf,NSString*methodName,Class cls);其中:
SEL表示Objective-C的方法标识;
ASConvertFunctionToSelector表示将第一私有方法转换成Objective-C运行时需要的方法标识(SEL);
SelectorFunction*sf表示第一私有方法的函数指针;
NSString*methodName表示第一私有方法转换成Objective-C运行时的对象方法名称,具有唯一性;
Class cls表示该第一私有方法所在类的类型。
在执行步骤S1031调用第一私有方法时,可将拟调用的第一私有方法的函数指针、对象方法名称、所在类的类型带入上述函数类型转换器(selector转换器)中。上述函数类型转换器的作用在于,将用C语言实现的、实质为C函数的第一私有方法转换成Objective-C运行时需要的OC方法(SEL),从而保证了在Objective-C里需要运行OC方法(SEL)的时候,可将第一私有方法无缝转换成该类对应的对象方法,作为事件响应方法传递给事件源对象,从而满足第一私有方法在Objective-C机制下的调用性能。
更进一步地,第一私有方法的函数指针的类型与第一私有方法所包含的参数的数量存在对应关系。例如,可以在此基础上根据第一私有方法所包含的参数的数量定义不同的函数类型转换器,具体如下:
SEL ASConvertFunctionToSelector(SelectorFunction*sf,NSString*methodName,Class cls);其中,SelectorFunction表示没有参数的第一私有方法的函数类型;
SEL ASConvertFunction1ToSelector(SelectorFunction1*sf,NSString*methodName,Class cls);其中,SelectorFunction1表示有1个参数的第一私有方法的函数类型;
SEL ASConvertFunction2ToSelector(SelectorFunction2*sf,NSString*methodName,Class cls);其中,SelectorFunction2表示有2个参数的第一私有方法的函数类型;
SEL ASConvertFunction3ToSelector(SelectorFunction3*sf,NSString*methodName,Class cls);其中,SelectorFunction3表示有3个参数的第一私有方法的函数类型;依此类推。
优选地,可以预先设定一预设数值,当第一私有方法中的参数的数量超出上述预设数值时,可以将部分或全部参数合并为数据结构,以便以数据结构的形式进行参数的传递。此时,可以选择SelectorFunction1、SelectorFunction2或SelectorFunction3中任何一种函数类型,将多个参数包装成一个数据结构实现参数的传递,将第一私有方法的函数逻辑的代码块(block)中的参数传递给采用函数类型转换器转换得到的OC方法(SEL)。
在设定上述预设数值时,可取为2或3,从而更好的满足oc开发的需要。
图4给出了函数类型转换器(selector转换器)的原理图。在采用本申请提供的selector转换器进行函数类型转换时,将私有函数(例如Func1、Func2等)、类标识(Class)、方法名称(MethodName)作为入参传入函数类型转换器(selector转换器)。函数类型转换器(selector转换器)将私有函数(Function)转换成代码块(Block),生成OC方法(SEL)。函数类型转换器还将代码块(Block)转换成函数实现(IMP),并最终将函数实现(IMP)、OC方法(SEL)和类标识(Class)绑定,输出Objective-C运行时所需的Selector。
第二方面,在以上提供的Objective-C机制下第一私有方法的实现方法及各优选实施例的基础之上,本申请还提供了Objective-C机制下私有方法的调用方法,包括:
采用函数类型转换器将第一私有方法转换为OC方法供调用;其中,函数类型转换器的参数包括第一私有方法的函数指针、第一私有方法的名称标识符和第一私有方法所属类的类型标识符;其中,第一私有方法根据以上描述的任一实现方法实现。
应用上述方案调用第一私有方法时,采用函数类型转换器,通过取私有方法的函数指针的方式,可将C函数的函数指针作为函数类型转换器的第一个参数,从而将采用C函数实现的上述私有方法转换成Objective-C机制所需要的方法,从而能够在Objective-C机制下正常调用私有方法,保证了上述私有方法在Objective-C机制下的运行性能。
优选地,上述第一私有方法的函数指针的类型与第一私有方法所包含的参数的数量存在对应关系;则采用函数类型转换器将第一私有方法转换为OC方法供调用,可包括:
当第一私有方法中的参数的数量超出预设数值时,将部分或全部参数合并为数据结构,以便以数据结构的形式进行参数的传递。
上述预设数值可取为2或3。
第三方面,本申请实施例还提供了一种与Objective-C机制下私有方法的实现方法相对应的实现装置,具体包括:
第一声明模块,用于当第一私有方法带有类实例的指针时,在类中按照C语言的静态方法声明第一私有方法;其中,第一私有方法的声明的参数包括第一私有方法的类实例的指针;
第一实现模块,用于当所述第一私有方法的实现需要访问私有变量时,采用指针访问保护器实现第一私有方法;其中,指针访问保护器的参数包括第一私有方法的类实例的指针和包含有第一私有方法的函数逻辑的代码块。
除此之外,上述实现装置还可包括:
第二声明模块,用于当第二私有方法不带有类实例的指针时,在类中按照C语言的静态方法声明第二私有方法;
第二实现模块,用于按照C语言函数的实现方式实现第二私有方法。
第四方面,本申请实施例还提供了一种Objective-C机制下私有方法的调用方法相对应的调用装置,具体包括:
第一调用模块,用于采用函数类型转换器将第一私有方法转换为OC方法供调用;其中,函数类型转换器的参数包括第一私有方法的函数指针、第一私有方法的名称标识符和第一私有方法所属类的类型标识符;
其中,第一私有方法根据以上所述的任一种实现方法或者以上所述的任一种实现装置实现。
除此之外,上述调用装置还可包括:
第二调用模块,用于按照C语言函数的调用方式调用第二私有方法;
其中,第二私有方法根据上述实现方法或者实现装置实现。
结合图5给出的原理示意图,当需要在Objective-C机制下声明私有变量时,如图5中声明的类私有变量val1、val2等,可以将Objective-C类的属性变量声明在.h文件,对外暴露,尽量避免声明到.m文件,而将Objective-C类的私有变量以iVar变量的形式声明在.m文件,不对外暴露。类私有变量的访问规则在于:在访问这些Objective-C私有变量时,非私有方法可以直接使用该私有变量的名称访问,私有方法通过类实例的指针访问私有变量。为防止空对象调用、访问或直接操作指针时引起的死机现象,可以定义指针访问保护器call_self_ivar,为访问私有变量(iVar)提供保护,从而即使类实例(self)为空,在使用私有变量时也不会导致程序运行中断。
当需要在Objective-C机制下声明私有变量时,对于不带类实例的指针(又可称为self指针)的普通私有方法(相当于以上实施例中所述的第二私有方法),按照C语言的静态方法声明即可。在实现和调用这种普通私有方法时,按照C语言的函数进行即可。这种普通私有方法的实质就是C函数,采用这种方式声明这种普通私有方法,利用C语言层面的函数作用域限制,使其对外部文件不可见(即使子类继承也不可见),这样,在外部源文件里即使知道其私有方法名,也无法调用,从而达到私有化的效果。但由于Objective-C在某些场景下不能直接使用C函数,如事件回调等,此时则需要声明、实现和调用上述实施例中所述的第一私有方法。
对于带有类实例的指针(又可称为self指针)的类私有方法(相当于以上实施例中所称的第一私有方法)而言,在声明时按照C语言的静态方法声明,同时将self指针作为方法声明的第一个参数。这种类私有方法在实现时可使用以上实施例中所给出的指针访问保护器call_self_ivar,函数逻辑在指针访问保护器的block(代码块)里实现。如果需要返回值,可通过在保护器外声明__block变量,将函数处理结果赋值给此__block变量之后再返回。在调用这种类私有方法时,通过以上实施例中所提供的私有方法函数类型转换器将实质为C函数的类私有方法转换为对应的Selector(即Objective-C所需要的方法)之后,作为事件响应方法传递给事件源对象,从而实现在Objective-C环境中也能调用第一私有方法。
采用本申请各实施例给出的类私有变量规则和类私有方法规则,可以防止同名属性变量的覆盖问题、防止同名私有方法的覆盖问题,还能用作事件处理,满足Objective-C机制下的方法调用性能需求。
综上所述,以上实施例给出的技术方案,在类中按照C语言的静态方法声明私有方法,利用C语言层面的函数作用域限制,使得该私有方法对外部文件不可见,即使子类继承时也不可见,从而确保C函数的代码块无法被程序其他部分访问。同时,采用静态方法声明,使得C函数的代码块随着类的定义被分配和装载,因此即使知道函数名称,该C函数也无法被类以外的方法或函数调用,从而实现了真正意义上的私有化。当上述私有方法带有类实例的指针时,将该私有方法的声明的参数取为上述类实例的指针,并采用指针访问保护器实现该私有方法,从而可以防止空对象的调用、访问或直接操作指针时引起的死机现象,有利于保证上述私有方法的运行性能。
进一步地,在调用上述私有方法时,采用函数类型转换器,通过取私有方法的函数指针的方式,将C函数的函数指针作为函数类型转换器的参数,从而将采用C函数实现的上述私有方法转换成Objective-C机制所需要的方法,从而能够在Objective-C机制下正常调用私有方法,保证了上述私有方法在Objective-C机制下的运行性能。
以上以Objective-C机制下的私有化解决方案为例,说明了本申请所提供的编程环境下私有方法的实现和调用。基于本申请实施例所给出的技术方案,本领域内的技术人员无需进行创造性劳动,即可将上述实施例所体现的技术方案应用到其他缺乏私有方法和私有变量的编程环境中,解决相似的技术问题,达到相应的技术效果。
本领域内的技术人员应明白,本发明的实施例可提供为方法、系统、或计算机程序产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、商品或者设备中还存在另外的相同要素。
本领域技术人员应明白,本申请的实施例可提供为方法、系统或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
以上所述仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。