1

假设应用程序中有汽车的概念。汽车是汽车的一个实例。有少量可能的汽车和大多数,但并非所有关于汽车的数据在设计时都是已知的。每种车都是单车;每个应用程序最多有一种 Car。*

由于它们是单例,并且由于它们被命名,因此暗示了一些糖。最重要的一点是:当我将“Car.h”导入文件时,我希望符号“MAFerrari”、“MAMercedes”和“MAMclauren”开始出现在我的自动完成中,只要代码完成认为我正在尝试提供 Car* 的实例。

我的下一个贪婪的愿望是我希望能够将实例方法发送到我的 MAFerrari 文字,例如 [MAFerrari topSpeed] 的意思是“获取与法拉利对应的 Car 的单例实例并将 topSpeed 发送给它”,但我完全承认琐碎的事情。即使是实用主义者也应该知道他们的乌托邦是什么样的。

最后,如果可能的话,我希望以简洁的方式将三辆车的常量属性声明为 Car.m 文件顶部的文字数据。

现在,再一次,我实际上并不期望所有这些都可以在 Objective C 中实现。我只是想知道我们离这一切有多近。

我最接近的想法是为每种类型的汽车子类化 Car 并为每种汽车提供一个 +sharedInstance 方法。sharedInstance 可以实现单例模式:如果它被初始化,则返回它,否则初始化它,存储它(在哪里?它应该是 Car 类层次结构的私有),然后返回它。每个子类都可以实现自己的初始化程序,其中包含该子类的默认值。

这是我不喜欢的地方:

  1. 我想每当我使用这些子类时,我都必须导入所有头文件。这绝对糟透了。还有其他方法吗?
  2. 我必须为这些子类中的每一个创建 .m/.h 文件对。这似乎是很多样板,因为它们没有独特的行为。
  3. [[MAFerrari sharedInstance] topSpeed] 不如 [MAFerrari topSpeed],但我承认这是微不足道的。

无论如何,你会怎么做?

*实际上,好奇的不是汽车,而是应用内购买资产。

4

2 回答 2

2

听起来你想要的只是一个全局变量。您可以创建一个任意命名的全局变量(例如 MAFerrari)并在其中粘贴您想要的任何内容 - 变量的内容是多个单例类的实例还是同一类的多个实例从这一点来看并不重要具有全局名称来引用对象的观点。

于 2013-06-03T17:42:10.703 回答
1

十分简单。

请注意,这些不是单例;它们只是存储在全局变量中的类的长期实例。

//  Bolt.h

#import <Foundation/Foundation.h>

@interface Bolt : NSObject

// Properties

- (instancetype)initWithLength:(NSUInteger)length
                      diameter:(NSUInteger)diam
                        thread:(NSUInteger)thread
                         grade:(NSUInteger)grade;

// etc.

@end

extern Bolt * twentyFiveByTwelveCoarseThreadGradeEightBolt;
extern Bolt * fiftyByTenFineThreadGradeFiveBolt;

//
//  Bolt.m

#import "Bolt.h"

Bolt * twentyFiveByTwelveCoarseThreadClassEightBolt;
Bolt * fiftyByTenFineThreadGradeFiveBolt;

// This will be run before main() but after classes are loaded
__attribute__((constructor))
static void initialize_global_Bolts(void) 
{
    twentyFiveByTwelveCoarseThreadClassEightBolt = [[Bolt alloc] initWithLength:25
                                                                       diameter:12
                                                                         thread:175
                                                                          grade:8];
    fiftyByTenFineThreadGradeFiveBolt = [[Bolt alloc] initWithLength:50
                                                            diameter:10
                                                              thread:1
                                                               grade:5];

}

@implementation Bolt

- (instancetype)initWithLength:(NSUInteger)length
                      diameter:(NSUInteger)diam
                        thread:(NSUInteger)thread
                         grade:(NSUInteger)grade
{
    // Do initialization
}

@end

现在,您可以[fiftyByTenFineThreadGradeFiveBolt maximumTorque];在任何地方执行 Bolt.h 导入的操作。

您不能将字典或其他文字放在顶层,因为它们解析为方法调用,不能在其他方法之外使用。

于 2013-06-03T19:03:10.480 回答