类扩展与类类别

类扩展 @interface Class ()功能更强大,可以将变量注入到类中,而类别 @interface Class (Category)不能。

还有什么其他的区别,以及什么时候应该在类扩展上使用类别?

61934 次浏览

The main difference is that with an extension, the compiler will expect you to implement the methods within your main @implementation, whereas with a category you have a separate @implementation block. So you should pretty much only use an extension at the top of your main .m file (the only place you should care about ivars, incidentally) -- it's meant to be just that, an extension.

Categories are an Objective-C language feature that let you add new methods to an existing class. Extensions are a special case of categories that let you define methods that must be implemented in the main implementation block.

Private declarations can be in class extensions, which mainly are some properties, because we have no need to declare a method before we call it.

ios extension similiar to c#,java abstract class or interface
ios category similiar to c# class extension

A class extension bears some similarity to a category, but it can only be added to a class for which you have the source code at compile time (the class is compiled at the same time as the class extension). The methods declared by a class extension are implemented in the @implementation block for the original class so you can’t, for example, declare a class extension on a framework class, such as a Cocoa or Cocoa Touch class like NSString.

The syntax to declare a class extension is similar to the syntax for a category, and looks like this:

@interface ClassName ()
@end

Because no name is given in the parentheses, class extensions are often referred to as anonymous categories.

Unlike regular categories, a class extension can add its own properties and instance variables to a class. If you declare a property in a class extension, like this:

@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end

IMHO, it's best to think of class extensions as private interface to a class. The primary interface (in your .h file) acts as the public interface which defines the class's behavioural contract with other classes.

Use class extensions to Hide Private Information

Class extensions are often used to extend the public interface with additional private methods or properties for use within the implementation of the class itself. It’s common, for example, to define a property as readonly in the interface, but as readwrite in a class extension declared above the implementation, in order that the internal methods of the class can change the property value directly.

As an example, the XYZPerson class might add a property called uniqueIdentifier, designed to keep track of information like a Social Security Number in the US.

It usually requires a large amount of paperwork to have a unique identifier assigned to an individual in the real world, so the XYZPerson class interface might declare this property as readonly, and provide some method that requests an identifier be assigned, like this:

@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end

In order for the XYZPerson class to be able to change the property internally, it makes sense to redeclare the property in a class extension that’s defined at the top of the implementation file for the class:

@property (readwrite) NSString *uniqueIdentifier;

Note: The readwrite attribute is optional, because it’s the default. You may like to use it when redeclaring a property, for clarity.