我正在构建一个使用共享项目来保存其业务逻辑的应用程序。
在此共享项目中,每个控制器都有一个等效项。
我使用T#
方法为控制器生成逻辑并将其附加到自身,如下所示:
ViewDidLoad
每个逻辑都有自己的实例变量等,当不使用它们时应将其丢弃
因此,例如(当我)从 public override void ViewDidLoad() {
base.ViewDidLoad();
_logic = new MyControllerLogic();
_logic.attach(this);
}
向后导航到MyController
时,或者如果我替换了应用程序的根视图控制器,则必须处理导航出/替换后的控制器背后的逻辑。 / p>
我应该在哪里做?
在项目的android部分中,我这样做的是:
MyFirstController
答案 0 :(得分:1)
您应该在视图控制器上使用Unwind Segue,这是知道何时关闭视图控制器的唯一可靠方法:
https://developer.apple.com/library/archive/technotes/tn2298/_index.html
这是一个Xamarin示例:
https://github.com/xamarin/recipes/tree/master/Recipes/ios/general/storyboard/unwind_segue
答案 1 :(得分:0)
Xamarin基于C#,并且使用C#垃圾收集器。您最应该做的就是致电GC.Collect();
如果要对内存管理进行细粒度的控制,则应使用Swift或Objective-C。
答案 2 :(得分:0)
对于那些徘徊的人,这是我最终的方法(这适用于Xamarin,但如果需要的话,它也可以适用于Swift):
我创建了以下课程,从现在开始,我所有的UIViewController
都将扩展该课程
public abstract class BaseViewController : UIViewController {
protected virtual void Finished() { }
protected virtual void backPressed() { } //this is just in case I wish to be notified when the user moves back
public override void ViewWillDisappear(bool animated) {
base.ViewWillDisappear(animated);
if (NavigationController != null && NavigationController.ViewControllers.ToList().FirstOrDefault(c => c == this) == null) {
backPressed();
Finished();
}
}
public override void DismissViewController(bool animated, [BlockProxy(typeof(AdAction))] Action completionHandler) {
base.DismissViewController(animated, completionHandler);
Finished();
}
public void Present(string storyboard, bool replace = false, bool animated = true) {
UIViewController vctl = UIStoryboard.FromName(storyboard, null).InstantiateInitialViewController();
if (replace) {
List<UIViewController> old = new List<UIViewController>();
if (UIApplication.SharedApplication.KeyWindow.RootViewController is UINavigationController nav) {
old.AddRange(nav.ViewControllers);
} else {
old.Add(UIApplication.SharedApplication.KeyWindow.RootViewController);
}
if (animated) {
UIView.Transition(
UIApplication.SharedApplication.KeyWindow
, 0.25
, UIViewAnimationOptions.TransitionCrossDissolve
, () => UIApplication.SharedApplication.KeyWindow.RootViewController = vctl
, () => {
old.ForEach(o => (old as BaseViewController)?.Finished());
});
} else {
UIApplication.SharedApplication.KeyWindow.RootViewController = vctl;
old.ForEach(o => (old as BaseViewController)?.Finished());
}
} else {
this.PresentViewController(vctl, animated, null));
}
}
public void AddController(string storyboard, string controller = null, bool animated = true) {
UIViewController ctl = getController(storyboard, controller);
this.NavigationController?.PushViewController(ctl, animated);
}
public static void ReplaceController(this UINavigationController me, string storyboard, string controller = null, bool animated = true) {
UIViewController ctl = getController(storyboard, controller);
UIViewController[] vcl = this.NavigationController?.ViewControllers;
if (vcl == null) return;
if (vcl.Length > 0) {
UIViewController old = vcl[vcl.Length - 1];
vcl[vcl.Length - 1] = ctl;
me.SetViewControllers(vcl, animated);
(old as BaseViewController)?.Finished();
} else {
me.PushViewController(ctl, animated);
}
}
private UIViewController getController(string storyboard, string controller = null) {
if (string.IsNullOrWhiteSpace(controller)) {
return UIStoryboard.FromName(storyboard, null).InstantiateInitialViewController();
}
return UIStoryboard.FromName(storyboard, null).InstantiateViewController(controller);
}
}
唯一的缺点是从现在开始,我必须始终使用Present来显示新的Controllers,并使用Add / ReplaceController来显示当前导航内的新Controllers。
如果有人有更好的主意,请告诉我,因为我必须对所有类型的控制器(UITabBarController等)执行上述操作,而这可能很难维护。
答案 3 :(得分:0)
代码应像这样
public class NavigationService
{
public void NavigateTo(string storyboardName)
{
//your logic to present storyboard
}
public void GoBack()
{
var poppedController = NavigationController.PopViewController(true);
poppedController.Dispose(); //or your method where you want preclean data;
}
}