ios 记录项目中所有UIViewController的类名

ruarlubt  于 2023-06-25  发布在  iOS
关注(0)|答案(7)|浏览(129)

我们已经收到了一个巨大项目从外包,我们正在试图“修复”。项目中有数百个视图控制器。我们的目标是轻松确定我们当前在设备上查看的类别。
我们的解决方案(没有工作,因此提出了SO问题)如下。
使用以下内容通过类别覆盖UIViewController的viewDidAppear方法:

-(void)viewDidAppear:(BOOL)animated
{
    NSLog(@"Current View Class: %@", NSStringFromClass(self.class));
    [self viewDidAppear:animated];
    //Also tried this:
    //[super viewDidAppear:animated];
}

此类别将被放在项目的**.pch中。
这将不需要在数百个视图控制器中放置额外的代码,并且可以轻松地打开和关闭。它不起作用,因为正如我们现在学到的,<meme*>不能简单地通过category<
/meme*>覆盖现有方法。
我们遗漏了什么!?

5hcedyr0

5hcedyr01#

答案是混合方法!下面是我们得出的结论:

#import "UIViewController+Logging.h"
#import <objc/runtime.h>

@implementation UIViewController (Logging)

-(void)swizzled_viewDidAppear:(BOOL)animated
{
    NSLog(@"Current View Class: %@", NSStringFromClass(self.class));
    [self swizzled_viewDidAppear:animated];
}

+ (void)load
{
    Method original, swizzled;

    original = class_getInstanceMethod(self, @selector(viewDidAppear:));
    swizzled = class_getInstanceMethod(self, @selector(swizzled_viewDidAppear:));

    method_exchangeImplementations(original, swizzled);

}
@end
8iwquhpp

8iwquhpp2#

viewWillAppear log

下面是一个在控制台中显示当前视图控制器类名时 * 打印 * 的解决方案:

  • 在Xcode中创建符号断点
    *Symbol-[UIViewController viewWillAppear:]
  • 对于Action,添加一个Debugger命令和以下表达式:expr -- (void) printf("🔘 %s\n", (char *)object_getClassName($arg1))
  • 选中 * 评估操作后自动继续 *。

每当我在项目中迷路时,这对我帮助很大!

deinit日志

您还可以添加日志来查看视图控制器deinit何时被调用:

  • 创建另一个符号断点
  • 对于符号,添加-[UIViewController dealloc]
  • 对于Action,添加一个Debugger命令和以下表达式:expr -- (void) printf("🗑 %s\n", (char *)object_getClassName($arg1))
  • 选中 * 评估操作后自动继续 *。

这是非常方便的,可以确保视图控制器从内存中释放出来,也是捕捉保留周期的一个很好的指示器。
注意:我不建议使用swizzling,因为它可能会使代码的可维护性降低。

6tdlim6h

6tdlim6h3#

这里有解决方案
在您的.pch文件中包括以下内容

#define UIViewController MyViewController
#import "MyViewController.h"

创建新的UIViewController子类为
.h档桉

#import <UIKit/UIKit.h>

#ifdef UIViewController
#undef UIViewController
#endif
@interface MyViewController : UIViewController

@end
#ifndef UIViewController
#define UIViewController MyViewController
#endif

和.m文件

#import "MyViewController.h"

@implementation MyViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"Current View Class: %@", NSStringFromClass(self.class));
}

@end
yfwxisqw

yfwxisqw4#

视图控制器是否共享一个公共基类?如果是这样的话,你可以把它放在[viewDidAppar:]的基类实现中。如果它们不共享一个共同的基础,那么这可能是一个值得的任务,因为无论如何它都可能是有用的(共同的分析代码等)。

moiiocjp

moiiocjp5#

您可以从Xcode中执行应用程序范围的查找和替换,但它不一定能找到每种情况(但您尝试的方法也不一定能找到)。你可以查找“[super viewDidLoad];“并替换为“[super viewDidLoad]; NSLog(@“当前视图类:%@",NSStringFromClass(self.class));“

8e2ybdfx

8e2ybdfx6#

应用程序是否使用导航控制器来显示视图控制器?如果是,您可以使用NavigationController的方法来报告当前的控制器:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        [self reportNewController:viewController];
    }

    - (void) reportNewController:(UIViewController *)viewController
    {
        NSString *name = viewController.title;
            NSLog(@"Name is %@",name);
    }
rqenqsqc

rqenqsqc7#

您可以使用swizzling方法。这里有一个很好的指南:http://nshipster.com/method-swizzling/

相关问题