如何从类方法返回自定义Objective-C对象?

时间:2012-01-24 20:28:37

标签: objective-c ios arrays

我的应用程序中有一组标记为Crop.h / Crop.m的Objective-C文件。里面是一个来自电子游戏的不同蔬菜的定制阵列 - 每种蔬菜都有名称,生长季节,成长天数等属性。

我需要编写一个循环遍历此数组的函数,并检查每个Crop名称值以查看它是否与我的视图标题(self.title)匹配。下面是两个裁剪对象的示例:

Crop *turnip = [[Crop alloc] init];
[turnip setName:@"Turnip"];
[turnip setSeason:@"Spring"];
[turnip setBagPrice:120];
[turnip setSaleValue:60];
[turnip setDaysToGrow:5];
[turnip setRenewableDays:0];

Crop *potato = [[Crop alloc] init];
[potato setName:@"Potato"];
[potato setSeason:@"Spring"];
[potato setBagPrice:150];
[potato setSaleValue:80];
[potato setDaysToGrow:8];
[potato setRenewableDays:0];

然后我在想的是调用一个名为 returnCropData:的新类函数,它将self.title作为参数。我只是不确定这是否是我最好的方法......我很感激iOS开发者的任何建议。

这是我到目前为止的简单类方法 - 没有数据匹配,因为我仍在试图找出哪个循环最好。我也在努力弄清楚在函数

上添加NSString参数的语法
+ (Crop *)returnCropData
{
    Crop *turnip = [[Crop alloc] init];
    [turnip setName:@"Turnip"];
    [turnip setSeason:@"Spring"];
    [turnip setBagPrice:120];
    [turnip setSaleValue:60];
    [turnip setDaysToGrow:5];
    [turnip setRenewableDays:0];

    // more crops here....

    NSMutableArray *cropListing = [[NSMutableArray alloc] init];
    [cropListing addObject:turnip];
    [cropListing addObject:potato];
    // add the other crops here...

    return potato; 
    // return any Crop value for now
}

1 个答案:

答案 0 :(得分:3)

Apple的Objective-C文档建议您对类方法(构造函数)使用objectWithParams:语法。因此,在您的情况下,您应该将现有方法名称更改为

+ (Crop *)cropWithName:(NSString *)name

并使用Crop *turnip = [Crop cropWithName:@"Turnip];

进行调用

然后在for循环中,您可以检查传入的名称是否等于[name isEqualToString:turnip.name]对象的名称。

这样可行,但似乎每次调用该方法时,您都会创建大量的Crop对象 - 您需要耗费大量时间,并且会在设备上占用大量内存。相反,您应该考虑制作一个使用字典来表示每种裁剪的plist文件,然后在您的创建方法中,您可以使用传入的名称来查找有关指定裁剪的所有其他信息。然后你可以只返回一个Crop实例,而不是实例化大量的实例。

这是Apple文档的链接,用于解释plists:

https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/PropertyLists/Introduction/Introduction.html

具体来说,在我想从plist中提取的任何对象中,我定义了以下方法,该方法从字典中获取值并设置对象的属性:

- (id)initWithDictionary:(NSDictionary *)dictionary
{
    self = [super init];

    [self setValuesForKeysWithDictionary:dictionary];

    return self;
}

然后在我想要访问数组数组的类中,我会创建一个合成的@property然后定义这个方法(在这种情况下,我有Song对象):

- (NSMutableArray *)songs
{
    if (_songs == nil)
    {
        NSArray *songDicts = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ChillMix" ofType:@"plist"]];

        _songs = [[NSMutableArray alloc] initWithCapacity:[songDicts count]];


        // Fast enumeration //
        for (NSDictionary *currDict in songDicts)
        {
            Song *song = [[Song alloc] initWithDictionary:currDict];
            [_songs addObject:song];
        }
    }
    return _songs;
}

以下是我开发的示例项目:https://github.com/Jlawr3nc3/MusicLibraryiOS

[NSArray arrayWithContentsOfFile:]应该是你最好的朋友。这很棒。如果您可以使用plist格式格式化XML,那么您可以使用一种格式。单。线。解析数据。 (PS普通的XML在iOS上解析是很烦人的,所以如果你可以避免直接的XML,这是一个巨大的时间节省)。

另外,我不确定基于视图标题创建裁剪对象的用例是什么。由于在实例化视图之前您已经知道裁剪的名称,因此可以创建裁剪对象并将视图的裁剪属性设置为您创建的裁剪对象,然后在viewDidLoad中执行self.title = self.crop.name; 。最后,如果您有UITableView个裁剪对象,则不应使用静态文本填充表格视图;而是使用从plist创建的对象填充它,然后在didSelectRowAtIndexPath:中,您可以[self.arrayOfCrops objectAtIndex:indexPath.row]获取您点击的对象,并将其与您加载的视图一起传递。无论如何,请查看Apple的示例代码,了解有关plists和tableviews等的更多信息,因为他们已经获得了大量关于这些内容的信息。