我对视图控制器和子类的理解

时间:2014-09-30 22:39:13

标签: ios objective-c uiviewcontroller

我最近询问a question我在UIViewControllers上错误使用实例变量的问题。我得到的答案揭示了另一个基本问题:我认为我可能也会使用UIViewControllers所有错误。

我的典型故事板看起来像这样:

enter image description here

如您所见,每个视图控制器都有一个自定义类。其中一个自定义类可能如下所示:

//  SecondViewController.h

#import <UIKit/UIKit.h>
#import "MasterViewController.h"

@interface SecondViewController : MasterViewController

@property (strong, nonatomic) NSData *incomingData;

@end


//  SecondViewController.m

#import "SecondViewController.h"
#import "ThirdViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // do stuff with data, then pass it on to next view controller.
}

@end

每个视图控制器都是MasterViewController的子类。在MasterViewController中,我通常会将全局内容放在用户状态验证中。这样,应用程序中的每个视图控制器都可以验证用户状态,而无需每次重新实现它。

关于那个incomingData属性...我不确定如何在UIViewControllers之间传递数据而不使用自定义类上的属性...因此有三个单独的自定义类,每个一个人没那么做。

所以这里对我来说是阴暗的......

  • 我应该将重要的方法和实例变量保存在&#34; master&#34;查看控制器,以便所有其他视图控制器可以子类化它并有权访问这些方法和变量?或者这太荒谬了吗?
  • 我是否因为没有使用适当的课程扩展或类别而为自己创造了更多的工作?这些会帮助我让事情变得更精简和有条理吗?

我当前的系统大部分都在工作,但是当我有很多很多视图控制器时,它们都会变得笨拙,每个视图控制器都有自己的自定义类。

3 个答案:

答案 0 :(得分:0)

你在这里有强耦合,这被认为是一件坏事。

假设你想要创建一个新的应用程序,并且想要从旧的应用程序中复制一个视图控制器,那么你将很难修改很多东西。

目标是实现弱耦合,这意味着项目中的每个类都可以彼此独立工作。

答案 1 :(得分:0)

您可以将数据存储为App Delegate上的属性,这是一个单例,因此您可以使用AppDelegate *appDelegate=[UIApplication sharedApplication].delegate;从任何类中获取引用。或者,您可以定义一个新的单例对象来存储数据。

您使用的模式是依赖注入,许多人更喜欢单一模式。

如果所有视图控制器都继承自同一个超类(MasterViewController)并且都具有相同的属性,那么您只需在超类中定义属性即可。

答案 2 :(得分:0)

显然,您可能已经完成的第一步,以及您是否完全掌握,是真正理解模型 - 视图 - 控制器模式。我用快速谷歌搜索做的一个非常好的教程是:http://codewithchris.com/how-to-make-iphone-apps-mvc-one-pattern-to-rule-them-all/

接下来我建议你的控制器不需要是UIViewController以外的任何子类。视图层次结构和类层次结构之间存在差异。在故事板中,您将概述视图层次结构 - 哪个视图/控制器指向下一个视图/控制器。他们都可以独立。即使不是彼此的子类,也不是先前控制器的子类,它们仍然可以传递数据。

您仍然可以直接通过属性传递数据。为什么不更具体地说明需要发送哪些数据?而不是发送通用NSData blob,而是指定一个控制器需要告诉下一个控制器。例如,如果您要将用户名从一个用户名传递到另一个用户名,请使用:

@property (nonatomic, strong) NSString *username;

对于第二个控制器,在第一个控制器中,设置它:

self.secondController.username = @"my name";

如果从第二个控制器到第三个控制器,您不需要用户名,请不要将其作为第三个控制器的属性。也许第三个控制器只显示一个数字:

@property (nonatomic, strong) NSNumber *someNumber;

从第二个控制器,只需设置其值:

self.thirdController.someNumber = @5;

现在,我喜欢使用一些全局变量和方法。当你有不需要实例化的辅助类时,这些有时很有用。一种方法是只有一个类变量:

FirstController.h:

+(NSString *)defaultName;

FirstController.m

+(NSString *)defaultName {
    return @"Default";
}

然后在第二个控制器中,您可以执行类似

的操作
self.username = [FirstController defaultName]

还有其他模式,比如委托模式,第二个控制器询问其委托(第一个控制器)用户名应该是什么:

self.username = [self.delegate username];

但为此你必须建立一个协议。 Ray Wenderlich通常有非常好的教程:http://www.raywenderlich.com/46988/ios-design-patterns