通过宏在 Objective-C 中进行严格类型检查
有时,在开发/调试过程中,我想确保对象属于某种类型:
PageTopBottom *newPage = [notification object];
assert([newPage isKindOfClass:[PageTopBottom class]]);
我已经对此进行了研究
#define assertType(_var_, _class_) assert([_var_ isKindOfClass:[_class_ class]])
,
PageTopBottom *newPage = (id)[notification object];
assertType(newPage, PageTopBottom);
但现在我想,如果可能的话,只使用
assertType(newPage)
是否可以获取信息关于变量的变量声明类型?
我不确定我是否正确地提出了这个问题,但是任何让我能够使用一个参数来断言类型的答案都会很棒。
Occasionally, during development/debugging, I want to ensure that an object is of a certain type:
PageTopBottom *newPage = [notification object];
assert([newPage isKindOfClass:[PageTopBottom class]]);
which I've worked into this
#define assertType(_var_, _class_) assert([_var_ isKindOfClass:[_class_ class]])
and
PageTopBottom *newPage = (id)[notification object];
assertType(newPage, PageTopBottom);
but now I'd like to, if possible, just use
assertType(newPage)
Is it possible to get information about a variable's declared type from the variable?
I'm not positive that I'm framing the question correctly, but any answer that gets me to be able to assertType with one parameter would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不会。当程序运行时,该信息就会丢失。在您的例子中,newPage 只是一个 32 或 64 位数字,它指向保存 Objective-C 对象的内存位。
我认为你原来的未宏版本是正确的做法:
这完美地记录了你所做的假设,即你假设 newPage 是 PageTopBottom 或其子类之一的实例,并且对于任何理解 Objective-C 的人来说都是完全清楚的。您的宏版本稍微混淆了这一点,因为在代码中遇到它的人可能会相信它断言 newPage 是 PageTopBottom 而不是它的子类之一(我想,您可以更改宏的名称来防止这种情况,但我只是不会打扰)。
编辑
您可以做的是将声明和断言合并为一个:
其工作方式如下:
No. By the time the program is running, that information is lost. In your case, newPage is just a 32 or 64 bit number that points to a bit of memory that holds an Objective-C object.
I think your original unmacro'd version is the right thing to do here:
That perfectly documents the assumption you are making i.e. that you assume newPage is an instance of PageTopBottom or one of its subclasses and it's completely clear to anybody who understands Objective-C. Your macro version slightly obfuscates that, in that somebody coming across it in the code might beleive it is asserting that newPage is a PageTopBottom and not one of its subclasses (you could change the name of the macro to prevent that, I suppose, but I just wouldn't bother).
Edit
What you could do is combine the declaration and assertion in one:
which would work like this:
嗯,对于 Objective-C++ 有两个选择:
编写模板函数
template void assertType(T* obj) { ... }
对于指针
X* x< /code>,使用
NSClassFromString([NSString stringWithUTF8String:typeid(*x).name()])
。如果不使用 C++,您也许可以使用 GCC 扩展
typeof
,但我不确定[typeof(*x) class]
是否是合法操作...Hmm, with Objective-C++ there are two options:
Write a template function
template void assertType(T* obj) { ... }
For a pointer
X* x
, useNSClassFromString([NSString stringWithUTF8String:typeid(*x).name()])
.Without using C++, you might be able to use GCC extension
typeof
, but I'm not sure if[typeof(*x) class]
is a legit operation...预处理器只处理文本;它不了解类型,这就是为什么它有时被认为是“危险的”。我认为这样做的唯一方法是将变量声明包装在宏中,我强烈建议不要这样做,并且实际上可能不会减少代码或复杂性。
另外,您不应该在转换之前检查类型吗?
The preprocessor only processes text; it has no knowledge of type, which is why it's sometimes considered 'dangerous'. The only way I could see doing it is wrapping the variable declarations in a macro, which I would strongly advise against, and probably wouldn't actually cut down on the code or complexity.
Also, shouldn't you check the type before casting?