简体   繁体   English

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

[英]How to Return a Custom Objective-C Object from a Class Method?

I have a set of Objective-C files in my app labeled Crop.h/Crop.m. 我的应用程序中有一组名为Crop.h / Crop.m的Objective-C文件。 Inside is a custom array of different vegetables from a video game - each vegetable has properties like a name, growing season, number of days to grow, etc. 内部是来自视频游戏的一系列自定义蔬菜,每种蔬菜都有其属性,例如名称,生长季节,生长天数等。

I need to write a function which loops through this array and checks each Crop name value to see if it matches with my view title (self.title). 我需要编写一个遍历此数组并检查每个作物名称值的函数,以查看它是否与我的视图标题(self.title)匹配。 Below is an example of two crop objects: 下面是两个裁剪对象的示例:

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];

Then what I'm thinking is calling a new class function titled returnCropData: which takes the self.title as a parameter. 然后我在想的是调用一个名为returnCropData:的新类函数,该函数将self.title作为参数。 I'm just not sure if this is my best method... I'd appreciate any suggestions from iOS devs. 我只是不确定这是否是我最好的方法...我将感谢iOS开发人员的任何建议。

Here's the simple class method I have so far - no data matching yet as I'm still trying to figure out which loop would be best. 到目前为止,这是我到目前为止使用的简单类方法-目前还没有数据匹配,因为我仍在尝试找出哪个循环最好。 I'm also struggling to figure out the syntax to add an NSString parameter onto the function 我也在努力找出将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
}

Apple's Objective-C docs recommend you use objectWithParams: grammar for class methods (constructors). Apple的Objective-C文档建议您对类方法(构造函数)使用objectWithParams:语法。 So in your case, you should change your existing method name to 因此,在您的情况下,应将现有方法名称更改为

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

And call it with Crop *turnip = [Crop cropWithName:@"Turnip]; 并使用Crop *turnip = [Crop cropWithName:@"Turnip];

and then in your for loop you can check if the passed in name equals the name of your object with [name isEqualToString:turnip.name] . 然后在for循环中,您可以使用[name isEqualToString:turnip.name]检查传入的名称是否等于对象的[name isEqualToString:turnip.name]

This will work, however it seems as though every time that method is called you're creating a ton of Crop objects - time intensive on your part, and memory intensive on the device. 这将起作用,但是似乎每次调用该方法时,您都会创建大量的Crop对象-一方面耗时,另一方面在设备上耗费内存。 Instead, you should look into making a plist file that uses a dictionary to represent each kind of Crop, and then in your creation method you can use your passed in name to look up all the other information about the specified crop. 相反,您应该研究制作一个使用字典表示每种作物的plist文件,然后在创建方法中,可以使用传入的名称查找有关指定作物的所有其他信息。 Then you can just return one instance of Crop instead of instantiating a massive amount. 然后,您只需返回一个Crop实例即可,而不是实例化大量实例。

Here's a link to Apple documentation that explains plists: 这是指向Apple文档的链接,该链接解释了胶合板:

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

Specifically, in any objects that I want to pull from a plist I define the following method that takes values from a dictionary and sets an object's properties: 具体来说,在要从plist中提取的任何对象中,我定义以下方法,该方法从字典中获取值并设置对象的属性:

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

    [self setValuesForKeysWithDictionary:dictionary];

    return self;
}

And then in a class where I want to access an array of data, I would create a synthesized @property and then define this method (in this case, I've got Song objects): 然后在要访问数据数组的类中,我将创建一个合成的@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;
}

Here is a sample project I've developed: https://github.com/Jlawr3nc3/MusicLibraryiOS 这是我开发的示例项目: https : //github.com/Jlawr3nc3/MusicLibraryiOS

[NSArray arrayWithContentsOfFile:] should be your new best friend. [NSArray arrayWithContentsOfFile:]应该是您最好的新朋友。 It's awesome. 这很棒。 If you can format your XML in plist format, you're down to one. 如果可以将XML格式化为plist格式,那么您就可以做到这一点。 single. 单。 line. 线。 to parse data. 解析数据。 (PS normal XML is annoying as hell to parse on iOS so this is a huge time save if you can avoid straight up XML). (PS普通XML在iOS上令人讨厌解析,因此,如果可以避免直接使用XML,这将节省大量时间)。

Also, I'm not sure what the use case would be for creating a crop object based on a view's title. 另外,我不确定基于视图标题创建裁剪对象的用例是什么。 Since you're already aware of the name of the crop before the view is instantiated, you could create a Crop object and set a Crop property of the view to the crop object you created, and then in viewDidLoad just do self.title = self.crop.name; 由于在实例化视图之前已经知道作物的名称,因此可以创建一个Crop对象并将视图的Crop属性设置为您创建的作物对象,然后在viewDidLoad中执行self.title = self.crop.name; . Finally, if you've got a UITableView of crop objects you shouldn't populate the table view with static text; 最后,如果您有一个裁剪对象的UITableView ,则不应使用静态文本填充表格视图。 instead populate it with objects you create from a plist, and then in didSelectRowAtIndexPath: you can do [self.arrayOfCrops objectAtIndex:indexPath.row] to get the object you tapped on, and pass it in with the view you load. 而是用从plist创建的对象填充它,然后在didSelectRowAtIndexPath:您可以执行[self.arrayOfCrops objectAtIndex:indexPath.row]来获取您点击的对象,并将其传递给您加载的视图。 Anyway, check out Apple's sample code for more info on plists and tableviews etc, 'cause they've got a lot of information on this exact stuff. 无论如何,请查看Apple的示例代码以获取有关plists和tableviews等的更多信息,因为他们在这个确切的东西上有很多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM