我知道NSStringFromClass。
我的问题涉及在继承树中的多个类中实现相同方法的情况,并且您希望调试关于它正在执行哪个类的信息。
示例:
让我们有三个类:A - > B - > C,继承如箭头所示。
如果每个方法都有方法foo(),则定义:
-(void) foo
{
// Do some work particular to the class it is in.
.....
//Each method ends with the debugging statement:
NSLog("In foo of class:%$",NSClassFromString([self class]));
}
当B类的foo调用[super foo]时会出现问题。当[super foo](即A类)到达NSLog语句时,[self class]返回B类,而不是A。
同样,如果C调用[super foo],super中的log语句将记录C类。
我想要做的是输出正在执行方法实现的类 - 所以如果类B调用[super foo],那么[A foo]中的log语句输出A类。
简单的方法是用表示类名的硬编码字符串替换NSClassFromString,但我想知道是否有更好的方法来执行此操作?
答案 0 :(得分:2)
您可以使用__PRETTY_FUNCTION__
同时包含类和方法名称:
NSLog(@"Greetings from %s", __PRETTY_FUNCTION__);
我不相信只有类名的编译时宏。
答案 1 :(得分:1)
类可能没有宏,但C语言中有__FILE__
和__LINE__
个宏。它们扩展到当前文件和行号。您可以在NSLog中使用它们。我记得它时使用__PRETTY_FUNCTION__
,但我记得__FILE__
和__LINE__
更多。
示例:
NSLog( @"%s %d", __FILE__, __LINE__ );
请记住,__FILE__
不是Objective-C字符串。
答案 2 :(得分:1)
当B类的foo调用[super foo]时会出现问题。当[超级 foo](即A类)到达NSLog语句,[self class]返回 B级,而不是A。
不确定。那是因为self
指向一个对象,并且该对象的类不会因为调用超类的方法而改变。
简单的方法是用硬编码字符串替换NSClassFromString 代表班级名称,但我想知道是否有更好的 这样做的方法?
正如其他人所指出的,您可以使用像__PRETTY_FUNCTION__
这样的宏,但我认为简单明了的方法是最好的。在编写代码时,您知道类的名称,因此您可以编写:
NSLog("In foo of class: %@", @"ClassA");
每个类都有自己的方法实现,因此每个类都可以在消息中打印自己的类名。当您编写将要在多个函数中使用的调试宏时,类似__PRETTY_FUNCTION__
的内容非常有用。情况并非如此。使用这种明显的方法可以更容易地看到正在发生的事情,这在调试期间很重要(我假设你在这里尝试做的事情)。
答案 3 :(得分:0)
我认为你必须使用class_getSuperclass
和class_getInstanceMethod
走上类层次结构,比较方法的差异。这样做是为了确定objc类,然后使用class_getName
或NSStringFromClass
来获取它的名字。
这看起来像是:
NSString* MONClassNameWhichImplementsMethod(id Self, SEL cmd);
和
- (void)method
{
NSLog(@"%@ - %@",
MONGetClassWhichImplementsMethod(self, _cmd),
NSStringFromSelector(_cmd)
);
}
和
// NOT COMPILED -- FOR ILLUSTRATION ONLY
Class MONClassWhichImplementsMethod(Class cls, SEL cmd) {
assert(cls && cmd && "srsly?");
Class super = class_getSuperclass(cls);
Method m1 = class_getInstanceMethod(cls, cmd);
assert(m1 && "srsly?");
Method m2 = class_getInstanceMethod(super, cmd);
if (0 == m2) {
return cls;
}
else if (m1 != m2) {
return cls;
}
else {
return MONClassWhichImplementsMethod(super, cmd);
}
}
NSString* MONClassNameWhichImplementsMethod(id Self, SEL cmd) {
return NSStringFromClass(MONClassNameWhichImplementsMethod(Self.class, cmd));
}
如果它从深度递归中爆炸,你还有另外一个问题。