Effective Objective-C 2.0 学习记录(二)
来源:互联网 发布:java get 中文乱码 编辑:程序博客网 时间:2024/06/06 10:57
Effective Objective-C 2.0 学习记录(一)
八、黑魔法(Method Swizzling)
在runtime时,可以向类中新增或替换选择器所对应的方法实现。这种方法不宜滥用。
用到的相关方法:
method class_getInstanceMethod(Class aClass, SEL aSelector) //返回aClass的名为aSelector的方法 //如果 swizzling 的是类方法, 采用如下的方式: Class class = object_getClass((id)self); ... Method originalMethod = class_getClassMethod(class, originalSelector); Method swizzledMethod = class_getClassMethod(class, swizzlingSelector);//添加新方法class_addMethod(,函数指针,对当前函数编码) BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) /* 参数说明: cls:被添加方法的类 name:可以理解为方法名, imp:实现这个方法的函数 types:一个定义该函数返回值类型和参数类型的字符串 */class_addMethod([EmptyClass class], @selector(say:), (IMP)say, "i@:@"); /* 其中types参数为"i@:@“,按顺序分别表示: i:返回值类型int,若是v则表示void @:参数id(self) ::SEL(_cmd) */
九、类对象
//每个结构体的首个成员是Class类的变量,该变量定义了对象所属的类,通常称为“is a”指针struct objc_object { Class isa OBJC_ISA_AVAILABILITY;};/// A pointer to an instance of a class.typedef struct objc_object *id;//此结构体存放类的“元数据”typedef struct objc_class *Class;struct objc_class { Class isa OBJC_ISA_AVAILABILITY;//每个Class都有一个isa指针#if !__OBJC2__ Class super_class //本类的父类 OBJC2_UNAVAILABLE; const char *name //类名 OBJC2_UNAVAILABLE; long version //类版本 OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE;//!*!供运行期使用的一些位标识。如:CLS_CLASS (0x1L)表示该类为普通class; CLS_META(0x2L)表示该类为metaclass等(runtime.h中有详细列出) long instance_size //实例大小 OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars //存储每个实例变量的内存地址 OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE;//!*!根据info的信息确定是类还是实例,运行什么函数方法等 struct objc_cache *cache //缓存 OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols //协议 OBJC2_UNAVAILABLE;#endif} OBJC2_UNAVAILABLE;
可以用类型信息查询方法来检视类继承体系
isMemberOfClass:判断出对象是否为某个特定类的实例
isKindOfClass:判断出对象是否为某类或攀升累的实例
Teacher *teacher = [[Teacher alloc] init];[teacher isKindOfClass:[Teacher class]];//yes[teacher isKindOfClass:[NSObject class]];//yes[teacher isMemberOfClass:[Teacher class];//yes[teacher isMemberOfClass:[NSObject class]];//no
注:1、每个实例都有一个指向Class对象的指针,泳衣表明其类型,而这些Class对象则构成了类的继承体系
2、如果对象类型无法在编译期确定,那么久应该使用类型信息查询来探知
3、尽量食用类型信息查询方法来确定对象类型,而不要直接比较类对象,因为某些对象可能实现了消息转发功能
十、理解NSCopying协议
在使用对象时经常需要拷贝它,在oc中此操作通过copy方法完成,如果想令自己的类支持拷贝操作,那就要实现NSCopying协议,该协议有个方法:
-(id)copyWithZone:(NSZone *)zone;//以前在开发程序时,会据此把内存分成不同的“区”(zone),而创建对象会在某个区里面。现在不用了,每个程序只有一个区:“默认区”(default zone)。不必担心zone这个参数。//.h文件@interface YCFPerson : NSObject<NSCopying>@property (nonatomic, copy, readonly) NSString *firstName;@property (nonatomic, copy, readonly) NSString *lastName;- (id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName;@end//.m文件@implementation YCFPerson- (id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName{ if (self == [super init]) { _firstName = firstName; _lastName = lastName; } return self;}//在当前这个copyWithZone中,我们直接把拷贝的对象交给“指定的初始化方法initWithFirstName”初始化,然而有时候,除了拷贝对象,还要完成其他一些操作,比如类对象中的数据结构可能并未在初始化方法中设置好,需要另行设置。-(id)copyWithZone:(NSZone *)zone{ //此处一定要通过[self class]方法返回的对象调用allocWithZone:方法。因为指针可能实际指向的是YCFPerson的子类。[self class]就可以返回正确的类的类型对象了。 YCFPerson *copy = [[[self class] allocWithZone:zone] initWithFirstName:_firstName andLastName:_lastName]; return copy;}
NSCopying协议与NSMutableCopying的区别主要是在于,返回的对象是否是可变类型的。遵循NSMutableCopying协议,需要实现如下方法
- (id)mutableCopyWithZone:(NSZone *)zone;//.h文件@interface YCFSon : NSObject<NSMutableCopying>@property (nonatomic, copy, readonly) NSString *firstName;@property (nonatomic, copy, readonly) NSString *lastName;- (id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName;@end//.m文件@implementation YCFSon- (id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName{ if (self == [super init]) { _firstName = firstName; _lastName = lastName; } return self;}- (id)mutableCopyWithZone:(NSZone *)zone{ YCFSon *copy = [[[self class] allocWithZone:zone] initWithFirstName:_firstName andLastName:_lastName]; return copy;}@end
注意:1、若返回一个 不可变的拷贝,需要实现NSCopying,若返回一个可变的拷贝,需要实现NSMutableCopying协议。
2、需要注意是“深拷贝”还是“浅拷贝”。深拷贝就是在拷贝对象自身时,将其底层数据也一并复制过来。浅拷贝只拷贝容器对象本身,而不复制其中的数据。
0 0
- Effective Objective-C 2.0 学习记录(二)
- Effective Objective-C 2.0 学习记录(一)
- Effective Objective-C 2.0 学习记录(三)
- Effective Objective-C(二)
- [摘要]Effective Objective-C 2.0(二)
- iOS-Effective Objective-C 2.0 读书笔记(二)
- Effective Objective-C 2.0 读书笔记 (二)
- 《Effective Objective-C 2.0》学习笔记1
- Effective Objective-C 2.0 学习笔记之一
- Effective Objective-C 2.0学习笔记(部分)
- Effective Objective-C 2.0 学习笔记
- Effective Objective-C 2.0 学习日记
- Effective Objective-C 2.0
- effective objective c 2.0
- 学习笔记:Effective Objective-C
- Effective Objective-C学习笔记
- Effective Objective-C 2.0(上)
- Effective Objective-C 2.0(下)
- 自定义注解,实现拦截器
- 进制转换
- 分析男人的3种不同的性格
- swift学习---基本数据类型
- linux编译mtd-utils工具
- Effective Objective-C 2.0 学习记录(二)
- React 相关
- 如何成为一个技术“牛人”
- Centos 6 Docker配置桥接网络
- Spring使用JdbcTemplate实现对数据库操作
- 125. Valid Palindrome
- iOS 自定义导航栏笔记
- 15.1 Swift深浅拷贝
- iOS 集成 第三方 QQ