2

来自 sublime 文本编辑器中的 ruby​​ on rails 我的文件夹布局有模型、视图和控制器文件夹,他可以很容易地识别什么是什么。

在 Objective-c 中,我刚刚为我正在关注的新教程创建了一个新项目。我有文件:

BullsEyeViewController.h BullsEyeViewController.m BullsEyeViewController.xib

看来xib文件就是视图。我知道 .h 文件用于声明,而 .m 用于我对这些声明的实现。这两个文件会被归类为控制器吗?

如果是这样,我将如何识别模型?我已经完成了来自 big-nerd-ranch 的枯燥但必要的 Objective-c 编程书籍,但是当谈到 Objective C 中的 MVC 时,我仍然感到有些困惑。

我现在正在做另一门课程,我想我会一劳永逸地解决这个问题。正如我所说,在 ruby​​ on rails 中,我可以轻松识别模型视图和控制器,但在 objetive-c 中,当我尝试时,我开始感到困惑。

xib是一个视图?但它的名称中有 viewcontroller,这让我有点扭曲。将不胜感激一些帮助清除这一切。假设我想创建一个处理我所有存储并与数据库通信的文件。从文件名结构的角度来看,这会如何?

此外,我现在将 appdelegate 文件放在支持文件夹中,以减少混淆。我想做的是创建一个模型、视图和控制器文件夹并将相关文件放入其中。

4

5 回答 5

5

我只是维持这个结构。

|view
|--all the .xib's and Storyboard
|Controller
|--All the View Controller both .h and .m file
|model
|--.h and .m file for each controller which would be call models.

例子。

|view
|--login.xib
|Controller
|--loginViewController.h
|--loginViewController.m
|model
|--loginModel.h
|--loginModel.m

在 LoginModel 中,我通常处理 API 调用并将所有 json 转换为对象 NSMutableDictionary 并将数据发送到控制器以进行进一步处理。

在 My loginController 中,它将对收到的数据执行操作。

示例:我正在使用 AFNetworking 进行 API 调用。

AFHTTPAPIClient.h

#import "AFHTTPClient.h"
#import "AFJSONRequestOperation.h"

@interface AFHTTPAPIClient : AFHTTPClient

+ (AFHTTPAPIClient *)sharedClient;

@end

AFHTTPAPIClient.m

#import "AFHTTPAPIClient.h"

@implementation AFHTTPAPIClient

// Singleton Instance
+ (AFHTTPAPIClient *)sharedClient {
    static AFHTTPAPIClient *sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedClient = [[AFHTTPAPIClient alloc] initWithBaseURL:[NSURL URLWithString:@"www.yourdomain.com"]];
    });
    return sharedClient;
}

- (id)initWithBaseURL:(NSURL *)url {

    self = [super initWithBaseURL:url];
    if (!self) {
        return nil;
    }
    [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [self setDefaultHeader:@"Accept" value:@"application/json"];

    return self;
}

@end

登录模型.h

#import "AFHTTPAPIClient.h"

+ (void)loginWith:(NSDictionary *)parameters withBlock:(void (^)(NSMutableDictionary *, NSError *))block;

登录模型.m

+ (void)loginWith:(NSDictionary *)parameters withBlock:(void (^)(NSMutableDictionary *, NSError *))block {
[[AFHTTPAPIClient sharedClient] postPath:@"/api/login" parameters:parameters
                                 success:^(AFHTTPRequestOperation *operation, id responseObject){
                                     NSLog(@"%@",responseObject);
                                     if (block) {
                                         block(responseObject, nil);
                                     }

                                 }
                                 failure:^(AFHTTPRequestOperation *operation,NSError *error){
                                     if (block) {
                                         block([NSArray array], error);
                                     }
                                 }];
}

然后最后在控制器中使用它们。

登录视图控制器.m

NSDictionary * loginParametes = [[NSDictionary alloc] initWithObjectsAndKeys:_txtUsername.text,@"username", _txtPassword.text,@"password",nil];
[LoginModel loginWith:loginParametes withBlock:^(NSMutableDictionary *loginInfo, NSError *error) {
    if (!error) {                    
        if([[loginInfo objectForKey:@"status"] boolValue]==YES){
                // Login Success
        }
        else {
                // Login Failure
        }
    }
    else {
                // API Responce failure if content type is not a valid json or valid status code.
    }
}];
于 2013-09-14T20:41:02.797 回答
4

没有编程语言真正强制 MVC 分离。Ruby of Rails 之类的框架有助于引导您使用 Ruby 语言进行 MVC 分离。

您可以安全地将文件移动到文件夹中,而不会出现太多问题,以使您的项目更容易理解。

在 UIKit 中,会发生以下情况:

意见

UIView 对象通常是视图。UIViews 可以与零到一个 UIViewController 相关联。UIView 可以序列化为 XIB 文件或故事板。

控制器

UIViewController 是视图控制器。实现 UIApplicationDelegate 的对象是主应用程序的控制器的控制器。UIViewController 也可以被子类化,使其成为 UISplitViewController、UINavigationController 和 UITabBarController 等控制器的控制器。

那么为什么 Xcode 将 XIB 文件命名为与对应的 UIViewController 同名呢?

UIViewControllerloadView分三个阶段在指定bundle 中搜索XIB 文件的实现。

  1. 对于指定包中名为nibNameif的 nibnibName不是 nil。
  2. 对于在指定包中命名为类名减去单词“Controller”的 nib。
  3. 对于指定包中名为类名的 nib。

这就是为什么当您loadView在子类中覆盖时,不会加载任何 nib。

因此,您可以安全地重命名您的 XIB 文件以删除“控制器”一词,只要您的 UIViewController 未在其nibName属性中指定值,一切仍然有效。为什么 Apple 决定让 Xcode 在使用控制器自动创建 nib 时选择第三种情况作为默认情况,这是任何人的猜测。

楷模

模型通常是 NSObject 的子类。当你使用 Core Data 时,模型是 NSManagedObject 的子类。它创建的 xml 文件就像一个 nib 文件——它只是模型元数据的序列化。

于 2013-09-16T21:33:02.663 回答
2

这是我在过去几周对 iOS 中的 MVC 范式的理解。与其他语言相比,iOS 编程中的 MVC 设计模式在目标 C 中实现时遵循的方法略有不同。根据 MVC 范例,您的 BullsEyeViewController 类是您的控制器。您的 .xib 文件是您的视图。Xcode 遵循根据您在创建项目窗口中指定的类命名文件的模式。您的模型类将实现您的应用程序逻辑。您的大部分数据库管理将由您的控制器处理。要遵守此处的 MVC,您必须以不同的方式创建模型类。模型类将通知控制器。控制器将完成更新视图和模型的工作。并响应视图中的用户操作。

于 2013-09-14T20:28:37.620 回答
1

不要被“视图控制器”中的“视图”所迷惑。

它通常是您的“控制器”。如果您使用 xib 文件或故事板,那么它们通常是您的“视图”。

模型,为了清楚地分开应该放在单独的文件中,但是,在许多教程中,模型将由“视图控制器”中的代码表示,并且通常是由数组或字典组成的数据存储。

学习时会让您感到困惑的领域是当您找到“查看”代码时,实际上是在代码中。当您看到类似 [self.view addSubView:someOtherView] 之类的代码以及大量创建 UI 元素并设置其框架和掩码等的代码时,通常可以识别这一点。

不要让这让你感到困惑。它们可能也应该在单独的文件中,但通常不会混合在一起。即使它在“视图控制器”中,它实际上也是 MVC 中的“V”。

在我记得读过的一些示例中,我当时并不知道,但后来意识到它们已经在单个视图控制器中表示了整个 MVC。这是很有可能的,尽管显然不推荐。

其他可能令人困惑的事情:类属性可以用作模型。例如,一组 25 张照片。您可能会在“视图控制器”中找到显示用于建立网络连接和检索照片的代码的示例,但这实际上是“M”代码。检索并存储照片后,该数据的持有者将成为模型。正确的方法是设计一个类来执行网络调用并将照片返回给控制器(视图控制器),然后可能调用一个用新数据更新 UI(视图)的方法。这经常混入视图控制器中,您可能会看到提供完成块的网络调用之类的东西,并且在完成块中,视图上的属性正在更新。在小“场景”中 如果该网络调用是引入模型数据的唯一调用,那么在控制器(视图控制器)中拥有该单个块语句可能确实更简单,更有效。但是,如果为检索数据进行了许多标注,那么它确实应该在其自己的类文件中隔离并成为“M”。

在大多数 IOS 应用程序中,您实际上会为每个“场景”或呈现的新视图获得一个新的 MVC。您实际上并没有一个控制器,而是很多。用我自己的话来说,我还会说您在 IOS 应用程序中具有“控制器的控制器”的概念。这些示例包括 appDelegate、导航控制器、标签栏控制器、拆分视图控制器。你可能还有一个模型控制器,例如 Core Data,一个通过其上下文控制许多模型对象的大控制器。如果你仔细想想,故事板实际上只是一个视图控制器。在这些情况下,您需要为每个场景挑选出特定的控制器、视图和模型对象并将它们连接在一起。

希望这会有所帮助,并且不会引起更多混乱。好起来。

于 2013-09-16T01:54:55.710 回答
1

正如您所见,XCode 不像 Rails 那样强制执行 MVC 结构。自从我使用 Rails 以来已经有几年了,所以我可能已经过时了,但这是我记得的:当你开始一个 Rails 项目时,你可以提供数据库文件,Rails 将使用这些文件来生成描述模型对象数据库实体,以及用于查看/编辑这些模型对象的视图,以及用于连接模型和视图的控制器。

当您在 XCode 中创建新的单视图应用程序时,它不会为您生成任何模型文件。它不能,因为它没有让您有机会在创建项目之前指定模型的外观。它所知道的是您将拥有一个视图,因此它会为您创建该视图(在 .xib 文件中)并为该视图创建一个控制器(在 .h 和 .m 文件中)。

.xib 文件以控制器命名。我总是觉得这很令人困惑,但这是 Apple 做出的决定。

您可以通过进入核心数据编辑器并创建一个新的核心数据模型(文件 -> 新建 -> 文件 -> 核心数据 -> 数据模型)来模拟 XCode 中的模型创建。填写此模型时,您可以通过选择已创建的实体并转到 Editor -> Create NSManagedObject Subclass 来创建描述新模型对象的文件;这将生成包装您描述的模型对象的 .h 和 .m 文件。

当然,您的模型对象不必由持久存储支持;您可以为它们创建新文件,而无需使用 Core Data 路线。但是 XCode 并没有像 Rails 那样强制执行目录结构。它会很高兴地将所有 MVC 文件放在同一个目录中。如果需要,您可以创建该结构。

xib是一个视图?但它的名称中有 viewcontroller,这让我有点扭曲。

是的-我同意,这令人困惑。XCode 以它们的控制器对象命名视图文件 (.xibs)。我不认为这是一个很好的方法,但是你有它。

简而言之:每当您向项目中添加新的视图文件时,XCode 都会自动为您创建视图和控制器文件。它永远不会(据我所知)为您显式创建模型文件,除非您使用核心数据编辑器,即使那样它也不会在文件名中放入“模型” - 它只是在实体之后命名文件你创造的。

于 2013-09-15T19:25:58.273 回答