【发布时间】:2016-04-11 19:15:49
【问题描述】:
我正在自学Objective C,并且我正在尝试使用模型-视图-控制器的概念来进步。我的问题是:在模型类中创建数据的正确方法是什么?我有一个例子来说明我的意思,它有点长,但一个非常简单的问题。
以下代码来自我刚刚完成的一个记忆游戏。它工作正常,我已将数据与视图控制器分开,因此我有一个单独的类来保存卡片的图像。这是那堂课。顺便说一句,这一切都有效,对我的问题来说唯一重要的是声明了一个数组,因此请随意跳过大部分复制图像和随机化的代码。无论如何,这里是:
导入“卡片.h”
@实现卡片
- (NSMutableArray*) createCardImages{
NSMutableArray *Fruits = [[NSMutableArray alloc] initWithObjects:
[UIImage imageNamed:@"Apple.png"],
[UIImage imageNamed:@"Banana.png"],
[UIImage imageNamed:@"Pear.png"],
[UIImage imageNamed:@"Strawberry.png"],
[UIImage imageNamed:@"Lemon.png"],
[UIImage imageNamed:@"Orange.png"],
[UIImage imageNamed:@"Pineapple.png"],
[UIImage imageNamed:@"Kiwi.png"],
[UIImage imageNamed:@"Prune.png"],
[UIImage imageNamed:@"Peach.png"],
nil];
NSUInteger tileCount = [Fruits count];
for (NSUInteger i = 0; i < tileCount; ++i) {
NSInteger nElements = tileCount - i;
NSInteger n = (arc4random() % nElements) + i;
[FullList exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSArray *Shortlistprep1 = [Fruits subarrayWithRange:NSMakeRange(0, 10)];
NSArray *ShortListprep2=[Shortlistprep1 arrayByAddingObjectsFromArray:Shortlistprep1];
NSMutableArray *ShortList = [[NSMutableArray alloc]init];
ShortList = [NSMutableArray arrayWithArray:ShortListprep2];
return ShortList;
}
- (NSMutableArray*) shuffleCards{
NSUInteger cardCount = [self.cardImages count];
NSMutableArray *count = [[NSMutableArray alloc]init];
for (int tileID = 0; tileID < cardCount; tileID++){
[count addObject:[NSNumber
numberWithInt:tileID]];
}
return count;
}
然后我从视图控制器调用此方法,一切正常。 接下来,我想添加一个不同的图像列表,以便在玩游戏时可以选择不同的图像集。比如:
NSMutableArray *Clothes = [[NSMutableArray alloc] initWithObjects:
[UIImage imageNamed:@"Hat.png"],
[UIImage imageNamed:@"Coat.png"],
[UIImage imageNamed:@"Gloves.png"],
[UIImage imageNamed:@"Trousers.png"],
[UIImage imageNamed:@"Socks.png"],
[UIImage imageNamed:@"Sweater.png"],
[UIImage imageNamed:@"T-shirt.png"],
[UIImage imageNamed:@"Shirt.png"],
[UIImage imageNamed:@"Jumper.png"],
[UIImage imageNamed:@"Underwear.png"],
nil];
我知道我可以为每个新集合复制整个方法,如下所示:
- (NSMutableArray*) createCardImagesClothes{
NSMutableArray *Clothes = [[NSMutableArray alloc] initWithObjects:
[UIImage imageNamed:@"Hat.png"],
[UIImage imageNamed:@"Coat.png"],
[UIImage imageNamed:@"Gloves.png"],
[UIImage imageNamed:@"Trousers.png"],
[UIImage imageNamed:@"Socks.png"],
[UIImage imageNamed:@"Sweater.png"],
[UIImage imageNamed:@"T-shirt.png"],
[UIImage imageNamed:@"Shirt.png"],
[UIImage imageNamed:@"Jumper.png"],
[UIImage imageNamed:@"Underwear.png"],
nil];
NSUInteger tileCount = [FullList count];
for (NSUInteger i = 0; i < tileCount; ++i) {
NSInteger nElements = tileCount - i;
NSInteger n = (arc4random() % nElements) + i;
[FullList exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSArray *Shortlistprep1 = [FullList subarrayWithRange:NSMakeRange(0, 10)];
NSArray *ShortListprep2=[Shortlistprep1 arrayByAddingObjectsFromArray:Shortlistprep1];
NSMutableArray *ShortList = [[NSMutableArray alloc]init];
ShortList = [NSMutableArray arrayWithArray:ShortListprep2];
return ShortList;
}
如果这是前进的道路,我很乐意这样做,我只是想学习最佳实践。我觉得应该有一种方法可以只编写一个方法,然后在 h 文件上声明属性:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Cards : NSObject
// Create Cards
@property NSMutableArray *cardImages;
@property NSMutableArray *shuffledCards;
@propery NSMutableArray *Fruits;
@propery NSMutableArray *Clothes;
@propery NSMutableArray *SomeOtherSet;
@propery NSMutableArray *SomeOtherSet;
@propery NSMutableArray *SomeOtherSet;
- (NSMutableArray*) createCardImages;
- (NSMutableArray*) shuffleCards;
@end
然后我要做的就是修改我的方法以接受 NSMutableArray 类型的参数,如下所示:
- (NSMutableArray*) createCardImages:(NSMutableArray);
只需使用代表我要加载的任何集合的参数调用该方法。
我的问题是一个相当基本的问题,即我将在哪里实际将信息加载到这些数组中。 “m”文件上没有“main”或“viewDidLoad”方法来实际将数据(在本例中为图像)加载到数组中。
这有意义吗?
感谢阅读。
【问题讨论】:
-
无论您的目标是什么,您可能需要注意 model 层仅存储/恢复/管理数据(例如 -
create...),但任何进一步的交互随着数据在逻辑上在 controller 层(例如-shuffle...)上启动,因此为了洗牌,在NSMutableArray上创建一个类别会更合理——但显然这是基于主观仅供参考 - 因为没有严格的规则说明为什么要这样做。 -
@holex - 实际上,在标准 MVC 中,模型层封装了数据以及与该数据相关的所有操作。我会打电话给
shuffle绝对是在一副纸牌上的正常操作,它应该放在模型层中。控制器层仅包含将模型映射到视图所需的功能。 -
@fishinear,实际上这是基于主要意见的,因为开发人员决定 model-layer 的结束位置以及 controller-layer 的开始位置; 这里唯一的规则是每一层都必须是可替换的,而不影响其他两层;像例如在 model 上,应用程序最初将所有内容存储在本地
plist文件中,但出于某种原因,您需要用 CoreData + iCloud 替换存储引擎,因此这种更改一定不会影响 控制器 或 view 层——如果它影响并且它们不能相同,那么当前的 MVC 模式是完全错误的。 -
@holex - 所有设计都是基于意见的。您所说的“唯一规则”实际上是所有OO设计的正常数据封装规则。但是成熟的 MVC 设计模式为每一层分配了特定的角色。但是这里不是讨论这个的地方。如果您想进一步讨论,请随时 PM 我。
-
感谢孔我明白你在说什么。我将考虑在 NSMutableArray 上创建一个类别,而不是我以前做过的事情。我如何将图像加载到卡片类的数组中?
标签: objective-c arrays model-view-controller