programmingwithobjectivec学习笔记(四)

来源:互联网 发布:idown mac 编辑:程序博客网 时间:2024/05/15 17:20

Customizing Existing Classes (对现有类进行修改及扩展)


CategoriesAdd Methods to Existing Classes 

用(Categories)给类添加方法(cateGory单独.h和.m文件)

XYZPerson.h文件(声明了XYZPerson类)

@interface XYZPerson:NSObject;
-(void)sayHello;@end

XYZPerson.m文件(XYZPerson的实现)

#import "XYZPerson.h"

  @implementation XYZPerson
-(void)sayHello{
}
@end

XYZPerson+XYZPersonNameDisplayAdditions.h (声明了XYZPerson的CateGories 对 XYZPerson类进行扩展)

括号内是category的名字

#import "XYZPerson.h"
@interface XYZPerson (XYZPersonNameDisplayAdditions)- (NSString *)lastNameFirstNameString;@end

XYZPerson+XYZPersonNameDisplayAdditions.m(Categories的实现)

#import "XYZPerson+XYZPersonNameDisplayAdditions.h"
  @implementation XYZPerson (XYZPersonNameDisplayAdditions)  - (NSString *)lastNameFirstNameString {
      return [NSString stringWithFormat:@"%@, %@", self.lastName, self.firstName];  }

@end


其他任何类中引用XYZPerson+XYZPersonNameDisplayAdditions.h就可以实例化并使用这个类及其在categories中追加的方法了

#import "XYZPerson+XYZPersonNameDisplayAdditions.h"@implementation SomeObject- (void)someMethod {
    XYZPerson *person = [[XYZPerson alloc] initWithFirstName:@"John"                                                    lastName:@"Doe"];
    XYZShoutingPerson *shoutingPerson =                        [[XYZShoutingPerson alloc] initWithFirstName:@"Monica"
                                                           lastName:@"Robinson"];

NSLog(@"The two people are %@ and %@",
[person lastNameFirstNameString], [shoutingPerson lastNameFirstNameString]);

}@end 


Avoid Category Method Name Clashes 

避免类别添加的方法名冲突,一般的做法是给category方法加前缀
定义
@interface NSSortDescriptor (XYZAdditions)- (id)xyz_sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending;@end
使用

NSSortDescriptor *descriptor =
[NSSortDescriptor xyz_sortDescriptorWithKey:@"name" ascending:YES]; 


ClassExtensions Extend the Internal Implementation 

Extension与category不同,括号内没有名字(官方说是一个匿名的Category),新添加的方法必须(mian implements)中实现(category没有这规定)
XYZPerson.m
@interface XYZPerson () {    id _someCustomInstanceVariable;//定义实例变量

}...

@property NSObject *extraProperty;//定义属性

@end 

@implements XYZPerson

...

@end

Use Class Extensions to Hide Private Information 

用Extension隐藏私有属性,如下例子
.h文件声明了readonly的属性uniqueIdentifier
 @interface XYZPerson : NSObject  ...  @property (readonly) NSString *uniqueIdentifier;
 - (void)assignUniqueIdentifier;  @end

.m文件

extension中将变量设置为readwrite
@interface XYZPerson ()@property (readwrite) NSString *uniqueIdentifier;@end
@implementation XYZPerson...@end
那么该extension所在的implements中此属性uniqueIdentifier就被改为了readwrie
个人理解是:当外部类实例化本类时uniqueIdentifier属性是readonly的,而在带有上面extension的本类实现中uniqueIdentifier却是readwrite的,类似于(java中的private)

Consider Other Alternatives for Class Customization 

考虑类的重用性,你可以使用继承创建子类,或者使用代理(delegate)对象(后一篇会学习,这里还不是很明白)

Interact Directly with the Objective-C Runtime 

哪个函数被调用,那个信息被送出,都不是在编译的时候,而是在运行时候被决定的。
obj-c的运行时系统,比如extension和associative reference(相关引用)不影响原始类的定义和实现。
总结:category只用来作为对源生类的扩展,单独.h和.m文件
extension只写在.m文件中,不被外界调用的属性和方法基本都写在extension内