您的位置:首页 > 编程语言 > Go语言

进阶之路(基础篇)OC——Category&Extension

2015-11-04 20:56 531 查看

category&extension

category

使用场景

1.为已经存在的类添加方法。

2.可以把类的实现放到不同的文件中。

3.声明私有方法。

表现形式

#import "ClassName.h"
@interface ClassName (CategoryName)
//method declarations
@end


使用注意

category的使用

声明:

@interface NSString(Add)
- (NSString *)Add:(NSString*)string;
@end


实现:

@implementation NSString(Add)
- (NSString *)Add:(NSString*)string
{
return [self stringByAppendingString:string];
}
@end


调用:

NSString *testString = @"Hello";

testString = [testString Add:@"World!"];
NSLog(@"%@", testString);


输出:

2015-11-04 20:22:14.000 TestIphone[9986:238906] HelloWorld!


因为category是在运行时决定的,所以其可以在没有类源码的情况下添加category,这也就导致了其不能不能添加实例变量。如果category想要访问类的任何实例变量,则必须导入其所扩展类的接口文件。当类别中的方法与原有类中的方法名冲突是,类别的方法将取而代之(置于方法链表的前面)。当category中出现方法名与原有类方法重名时,category的方法被加入的方法列表的前面,而原理的类方法则处于新方法列表的后面。这就造成了我们所见的category方法覆盖了原有类的同名方法。主要是因为运行时查找方法的时候是沿着方法列表顺序查找的,只要找到对应的方法即返回。

也正因为category是运行时决定的,所以可以通过runtime机制添加实例变量。主要API为:

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
id objc_getAssociatedObject(id object, const void *key)


使用示例:

声明:

@interface NSString(Add)
@property (nonatomic, strong)NSString *myNameString;
- (NSString *)Add:(NSString*)string;
@end


实现:

#import "objc/runtime.h"

static const char *myNameString = "myNameString";
@implementation NSString(Add)
- (NSString *)Add:(NSString*)string
{
return [self stringByAppendingString:string];
}

// get方法
- (NSString *)myNameString {
return (NSString *)objc_getAssociatedObject(self, myNameString);
}
// set方法
- (void)setMyNameString:(NSString *)nameString {
objc_setAssociatedObject(self, myNameString, nameString, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}


调用:

NSString *testName = [[NSString alloc] init];
testName.myNameString = @"zhanyawei";
NSLog(@"%@", testName.myNameString);


输出:

2015-11-04 20:31:58.496 TestIphone[10008:242495] zhanyawei


extension

使用场景

1.隐藏类的私有信息。

表现形式

#import "ClassName.h"
@interface ClassName ()
//method declarations
@end


使用注意

常用于声明公有的只读属性和私有的读写属性。

比如:

@interface MyClass : NSObject
@property (retain, readonly) float value;
@end

// 私有的extension, 隐藏在主实现文件中.
@interface MyClass ()
@property (retain, readwrite) float value;
@end


extension和category行驶时看起来差不多,但是其行为却差别很大。extension在编译期和原有的类一起编译成一个完整的类,其与原有的类‘同生共死’。所以定义extension需要原有类的源码,也可以定义实例变量。

参考

Cocoa Core Competencies

Dive into Category
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  category extension