Gre*_*reg 6 objective-c objective-c-runtime
Objective-C @encode生成C字符串来表示任何类型,包括基元和类,如下所示:
NSLog(@"%s", @encode(int)); // i
NSLog(@"%s", @encode(float)); // f
NSLog(@"%s", @encode(CGRect)); // {CGRect={CGPoint=ff}{CGSize=ff}}
NSLog(@"%s", @encode(NSString)); // {NSString=#}
NSLog(@"%s", @encode(UIView)); // {UIView=#@@@@fi@@I{?=b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b6b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b3b1b1b1b2b2b1}}
Run Code Online (Sandbox Code Playgroud)
因此,我可以使用一个有意义的类(包含类名称)编码@encode(ClassName),但它的格式与泛型的编码相同struct(如上例所示).
现在,我的问题是,给定任何(当然有效)类型编码,是否可以找出编码是否是Objective-C类,如果是,那么获取Class对应于该编码的对象?
当然,我大概可以只尝试解析类名出的编码类型,并从使用获取类NSClassFromString,但只是听起来并不像正确的方式去做,或者特别的性能效率.这真的是实现这一目标的最佳方式吗?
不幸的是,我认为没有办法确定您正在使用编码的类.
dasblinkenlight在评论中有一个好主意,虽然他不支持其他实例变量.一个类的完整格式是{CLASSNAME=#IVARS}.但是,这可能会捕获其他结构,我将在下面解释.
类被编码的原因是它们被视为结构@encode.该{指示结构的开始,接着是结构的名称和一个等号,然后将内容,最后}.所有类#在等号后面的原因是类结构中的第一个元素是类型Class,这就是这种类型的编码方式.这意味着以a开头的任何结构Class都将匹配此格式.如果列出了任何实例变量,它们将在之后进行编码#.例如,这里是使用您发布的编码重建UIView.
Structure Encoding
struct UIView { {UIView=
Class class1; #
id id1, id2, id3, id4; @@@@ Object pointers always encode as id.
float float1; f
int int1; i
id id5, id6; @@
unsigned int uint1; I
struct /*anonymous*/ { {?=
unsigned bitfield1 : 1; b1 The type of bitfield is not encoded.
unsigned bitfield2 : 1; b1 I just chose unsigned.
...
unsigned bitfield15 : 1; b1
unsigned bitfield16 : 6; b6
unsigned bitfield17 : 1; b1
...
unsigned bitfield58 : 1; b1
unsigned bitfield59 : 3; b3
unsigned bitfield60 : 1; b1
unsigned bitfield61 : 1; b1
unsigned bitfield62 : 1; b1
unsigned bitfield63 : 2; b2
unsigned bitfield64 : 2; b2
unsigned bitfield65 : 1; b1
}; }
} }
Run Code Online (Sandbox Code Playgroud)
(使用_C_*/usr/include/objc/runtime.h中的常量解码)
如果你把这个结构在你的代码(在填充...S),两者@encode(UIView)并@encode(struct UIView)会给你同样的结果.有趣的是,从技术上开始一个类的结构会使它成为一个有效的类类型,并且您可以成功地将消息发送到指向一个类的指针.但是,请注意,只有类接口中定义的实例变量才会放在编码中,因为其他位置是在运行时确定的,因此不建议使用此方法来创建自己的对象.
| 归档时间: |
|
| 查看次数: |
2488 次 |
| 最近记录: |