use*_*482 1 objective-c circular-dependency ios
我正在尝试在我AppDelegate和我之间实现循环依赖,ViewController以从我AppDelegate到我调用方法,ViewController但是它不起作用。
请参阅我的代码,如下所示:
AppDelegate.h:
@class ViewController;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong,nonatomic) ViewController *mainView;
@end;
Run Code Online (Sandbox Code Playgroud)
AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
[self.mainView doSomething];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
ViewController.h:
#import <UIKit/UIKit.h>
@class AppDelegate;
@interface ViewController : UIViewController
@property (strong,nonatomic) AppDelegate *delegate;
-(void)doSomething;
@end;
Run Code Online (Sandbox Code Playgroud)
ViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
}
- (void)doSomething
{
NSLog(@"doing something");
}
Run Code Online (Sandbox Code Playgroud)
我没有任何错误或警告,但doSomething从未调用过该方法。你们谁都知道为什么或我做错了什么?
非常感谢您的帮助。
这与循环依赖无关。
如您所知,doSomething永远不会调用该方法,因为您在说
[self.mainView doSomething];
Run Code Online (Sandbox Code Playgroud)
...在self.mainView从未被赋予价值的时候。仅声明财产
@property (strong,nonatomic) ViewController *mainView;
Run Code Online (Sandbox Code Playgroud)
...不会将变量指向mainView您实际的 ViewController实例;它是nil,并且一条消息不会nil产生任何错误,也不会导致任何事情发生。
您可以通过在代码中添加一行来让ViewController设置对自身的引用来解决此问题:
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
self.delegate.mainView = self; // <--
}
Run Code Online (Sandbox Code Playgroud)
但是不要!一个简单的事实是,您的整个方法都是错误的。在您的应用程序委托中,无需保留对ViewController的引用。您的应用随时都有一个视图控制器层次结构。应用程序委托应该知道ViewController在该层次结构中的位置。
当出现链接消息时,我们在您的应用程序委托中:
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
Run Code Online (Sandbox Code Playgroud)
那时,应用程序委托人的工作是知道 ViewController在视图控制器层次结构中的位置,甚至安排视图控制器层次结构,以便响应链接消息,显示ViewController的场景是否还存在。
如何执行取决于视图控制器层次结构的结构。您从层次结构的顶部开始,对于应用程序委托,层次结构的顶部是[[self window] rootViewController],然后一直向下移动到要与之对话的现有视图控制器。
您尚未告诉我们您的视图控制器层次结构,因此无法提供详细帮助。但是,例如,假设您的应用围绕导航控制器界面旋转。然后,对于应用程序委托,[[self window] rootViewController]是导航控制器,因此可以将其强制转换为该类:(UINavigationController*)[[self window] rootViewController]。然后,如果ViewController是导航控制器的根视图控制器,viewControllers[0]则将其拿到,然后根据需要再次进行投射:
UINavigationController* nav = (UINavigationController*)[[self window] rootViewController];
ViewController* vc = (ViewController*)nav.viewControllers[0];
Run Code Online (Sandbox Code Playgroud)
现在您可以将doSomething消息发送到vc。但这仅是一个例子。具体的细节取决于ViewController层次结构中ViewController的实际位置。当然,您可能还想弹出视图控制器,以便实际上显示 ViewController的场景,因为您可能无法保证在出现链接消息时就显示了它。
处理这种情况的另一种完全不同的方法是使用NSNotificationCenter 发布 ViewController实例已为其注册的通知。当您不完全知道视图控制器在视图控制器层次结构中的什么位置时,通常这是一种解决方案。但是在这种情况下,您应该知道这一点。
| 归档时间: |
|
| 查看次数: |
314 次 |
| 最近记录: |