选择单身人士还是分类?

时间:2012-03-07 05:01:08

标签: objective-c ios animation singleton categories

在我的应用程序的早期,当我的经验比我现在少得多时,我想用我自己的自定义动画为视图控制器之间的一些过渡增添趣味。我不知道从哪里开始,我四处寻找像MVC这样的模式,可以随时从几乎任何控制器访问,事实证明,单身就可以了。

我没有意识到的是,对单身人士模式似乎有一种强烈且善意的仇恨,而我自己也开始明白为什么,但这就不合时宜了。

所以,不久之后,我决定将我的相同实现移动到UINavigationController上的一个类别(毕竟,它处理转换!),保留原始类以进行比较,并且想知道哪种方法最有效。在对这两种实现进行全面测试后,我可以毫无疑问地说它们在各个方面都是相同的,包括速度,准确度,平滑度,帧速率,内存使用等等,那么从总体可维护性的角度来看哪一个更“好”?

编辑:在阅读了你们所写的精心编写的论据后,我决定使用单身人士。 @JustinXXVII已经提出了最有说服力的论点(恕我直言),虽然我认为这里的每个答案同样值得称道。谢谢大家的意见,我在问题中提出了所有答案。

6 个答案:

答案 0 :(得分:6)

我认为最好的选择是使用类别。

因为如果你已经在使用UINavigationController,那么创建一个只管理转换的新类是没有意义的,就像你告诉的那样:(after all, it handles transitions!)

这将是维护代码的更好选择,并且您将确保事情按预期执行,如果您已经有一个实例进行转换,为什么要创建另一个?

设计模式,如单身人士,工厂等,需要负责任地使用。在你的情况下,我不明白为什么使用单例,你只使用它来实例化新对象,你真的不需要只有一个实例,但你这样做是因为你只想要一个。

答案 1 :(得分:3)

我将为单例对象创建案例。单身人士遍布UIKitiOS。您无法对类别执行的操作是添加实例变量。关于这一点有两件事:

  1. MVC工作流程不容忍对其他对象有深入了解的对象
  2. 有时你只需要一个地方来引用一个并不属于其他任何地方的对象
  3. 这些事情彼此相反,但能够保留一个实际上没有“所有者”的实例变量的附加能力是我喜欢单身人士的原因。

    我通常在我的所有XCode项目中都有一个单例类,用于存储“全局”对象,并做一些我不想给AppDelegate带来负担的普通事物。

    一个例子是序列化/存档对象和取消存档/恢复。我必须在几个类中使用相同的方法,我不想使用一些序列化方法扩展UIViewController来编写和读取任意文件。也许这只是我个人的偏好。

    我也可能需要一种快速的方法来查找NSUserDefaults中的信息但不想总是写[[NSUserDefaults standardUserDefaults]stringForKey:@"blah"],所以我将在我的单例中声明一个带有字符串参数的方法。

    到目前为止,我并没有真正考虑过为这些事情使用类别。但有一件事是肯定的,当我只有一个生物对象可以帮我处理时,我宁愿不要将一个新对象实例化一百次以完成同样的任务。 (不会给AppDelegate带来负担)

答案 2 :(得分:3)

我认为真正的问题在于“设计”(如你所说,两种代码都可以正常工作),并且通过简单的句子写下你的问题,你会找到答案:

  • singleton的目的是在您的应用中只运行一个类的一个实例。所以你可以在对象之间共享东西。 (一个可用于许多对象)

  • 类别目的是扩展 a 类可用的方法。 (仅适用于一类对象!ok ...来自子类的对象)

你真正想要的是为UINavigationController类提供一个新的转换。 UINavigationController,它已经有一些可用于更改视图的方法(当前模态视图,addsubviews等),用于管理具有转换的视图(您自己说,它处理转换),您要做的只是添加另一个处理导航控制器转换的方法因此您最好使用类别。

我的观点是,您希望实现的内容由类别涵盖,通过这样做,您可以确保访问此方法的唯一对象有权使用它。使用单例模式,任何类的任何对象都可以调用你的单例及其方法(并且......如果没有人知道如何使用操作系统版本n,但你的应用程序可以在n + 1版本中被破坏,则可能无法工作)。

答案 3 :(得分:2)

在此实现中,不需要使用Singleton,可能没有任何区别。这并不意味着没有一个。

塑料桶可容纳与金属桶一样多的水,而且它也可以。在这方面,两者似乎没有区别。但是,如果你试图运输极热的东西,那么塑料桶可能无法很好地完成工作......

我想说的是,他们都是为了他们的目的,但在你的情况下似乎没有区别,因为任务太过一般。你想要一个可以从多个类中获得的方法,两个解决方案都可以做到这一点。

但是,在您的情况下,使用类别可能会更加简单。实现更容易,您(可能)需要更少的代码。

但是如果你要创建一个数据管理器来保存一个你只想在一个地方可用的对象数组,那么一个类别将无法完成任务。这是典型的Singleton任务。 Singeltons是单实例对象(如果是静态的,几乎可以在任何地方使用)。类别是现有类的扩展,仅限于它扩展的类。

回答你的问题;选择一个类别。

*子类也可能有效,但有自己的优点和缺点

答案 4 :(得分:2)

为什么不简单地创建一个基本的UIViewController子类并从该对象扩展所有视图控制器?一个类别对此没有意义。

答案 5 :(得分:1)

单身人士,顾名思义,必须在你的应用程序中只需一个对象时使用。访问器方法的模式确保只有这个要求是一个类方法:

+ (MyClass*) sharedInstance
{
    static MyClass *instance = nil;
    if (instance == nil)  instance = [[MyClass alloc] init];
    return instance;
}

如果实现良好,该类还确保其构造函数是私有的,因此没有其他人可以实例化该类,但是访问器方法:这确保了在任何时候最多只有一个类的实例存在。这类的最好例子是UIApplication,因为在任何时候这个类可能只有一个对象。

这里的要点是,这是对单身人士的唯一要求。访问器方法的作用是确保只有一个实例,而不是从任何地方提供对该实例的访问。它只是模式的副作用,访问器方法是静态的,每个人都可以访问这个单个对象,而不需要先验地引用它(指针)。不幸的是,这个事实被Objective C程序员广泛滥用,这导致了混乱的设计和对你提到的单身模式的仇恨。但总而言之,这不是单身模式的错误,而是滥用其存取方法。

现在回到你的问题:如果你的自定义转换代码中不需要静态/全局变量(我猜你没有),那么答案肯定是针对类别的。在C ++中,您将从一些父BaseTransition类继承子类并实现您的实际绘图方法。 Objective C有一些类别(在我看来是另一种容易弄乱设计的方法,但它们更方便),你可以添加自定义功能,甚至访问主机类的变量。无论何时你可以用它们兑换单身人士而不使用单身人士,当你对你的班级的主要要求不是它只是它的一个实例时,就使用它们。

相关问题