何时使用Categories-C?

时间:2014-04-15 13:39:42

标签: ios objective-c oop objective-c-category

如果我有方法将动画附加到UI Element,而不是复制/粘贴此方法的代码到很多viewcontrollers,我可以创建一个class保存方法然后导入它?

我认为在此实例中使用category没有意义,因为我需要多个viewcontrollers中的此方法,category是单个viewcontroller的扩展名1}}。

6 个答案:

答案 0 :(得分:17)

类别是类的扩展,而不是类的特定实例。并且,类别对类所做的任何修改都可用于所有子类(与OOP中的类上的其他方法一样)。

因此,如果您在NSObject上添加类别,基本上整个应用中的所有类都可以访问该类别中的方法 - 因此您需要非常小心在那里添加哪些方法。

在很多情况下,无论是添加类别还是助手类都是个人偏好,两者都可以。

答案 1 :(得分:12)

2015年4月9日编辑

您有两个基本选择:

创建一个类别,或创建一个自定义子类。

分类

类别允许您将方法添加到整个班级,甚至是您没有源代码的班级。类别对于向系统类中创建对象的系统类添加新方法特别有用,在这种情况下,您无法更改内容以创建自定义子类。

您可以将类别添加到基类(如UIView),并且您添加的方法可用于该类及其所有子类。因此,您可以向UIView添加动画类别,然后所有UIView对象(包括图像视图,按钮,滑块等)都将获得该类别中定义的方法。

类别可帮助您解决Objective-C中没有多重继承这一事实。 (在上面向UIViews添加动画行为的示例中,您不能创建UIView AnimationView的子类,然后创建一个继承UITextView和AnimationView的UITextView,并创建一个继承自AnimationView的UIImageView。)

类别存在一些重大限制:

  1. 他们无法真正覆盖已有方法的代码。 (他们可以,但你不能调用超级实现,如果有多个类别使用相同方法的实现,结果是未定义的,所以你不应该这样做。)

  2. 类别无法将新的实例变量添加到它们扩展的类中。 (有很多方法可以使用称为关联存储的技术来模拟这种情况,但这超出了本文的范围

  3. 自定义子类

    自定义子类可以覆盖现有方法。它还可以添加新方法,属性和实例变量。但是,它不能像现有类别那样将方法添加到现有的子类中。

答案 2 :(得分:2)

为什么要通过示例使用类别:

假设您有一个基类引擎,它由Car,Bike和Scooter等类继承。公司刚刚启动并愿意添加之前未提供的维护功能。

汽车,自行车和滑板车的发动机将根据相同的政策进行维护。因此,最好在Engine类中添加更多功能,而不是每个Vehicle。在这样做时,我们不应该改变Engine类,因为它可能无法改变。只需创建一个类别

Engine+Maintenance 

并且您在维护中提供的所有功能都将在所有子类中提供。更好的方法。

类别是将单个类定义拆分为多个文件的一种方法。他们的目标是通过模块化类来减轻维护大型代码库的负担。这可以防止您的源代码成为无法导航的单片10000+行文件,并且可以轻松地将类的特定的,明确定义的部分分配给各个开发人员

答案 3 :(得分:1)

类别是子类别的替代。当我们向现有类添加方法时,它将成为该类方法的一部分。因此,该类的任何实例都可以访问该方法。但是,这并不意味着当您将方法添加到某些现有类(如NSString或NSArray)时,该类将通常将您的方法添加到其定义中。它只表示在该项目中,您的NSString或NSArray类将具有您定义的另一个方法,并且对其进行子类化的任何类(在该特定项目内)或创建该类的实例将具有该方法作为该课程定义的一部分。

因此,您可以通过类别向该UI元素的UIView类添加方法,将动画添加到所需的UI元素。假设您的UI元素是一个按钮。现在,如果您为UIButton创建一个类别,那么无论何时创建UIButton实例,您都可以自动拥有一个方法来为其设置动画。

答案 4 :(得分:1)

子类化是向对象添加功能的一种方法,但通过使用类别避免不必要的子类化将有助于减少代码量并使项目更有条理。

https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html

答案 5 :(得分:0)

类别是特定类的子类。例如,如果您想要在没有编程代码的情况下更改标签的文本颜色,背景和字体,那么您必须制作UILabel类的软件。