programmingwithobjectivec学习笔记(四)

本文介绍了Objective-C中通过Categories和Extensions来扩展已有类的方法。Categories允许添加新的方法而不改变原始类,而Extensions则用于隐藏私有接口。文章还讨论了如何避免方法名冲突以及类别在实际开发中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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内
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值