<pre name="code" class="objc">
OC中的类目
// ViewController.m
// OC-09_01
//
// Created by Ibokan on 15/12/21.
// Copyright © 2015年 ibokan. All rights reserved.
//
#import "ViewController.h"
#import "Tool.h"
#import "Tool+Tool_Category.h"
#import "MyClass.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//类目,延展,协议
#pragma mark~~~~~~~~~~~~~~类目~~~~~~~~~~~~~~
/*
类目
定义:为现有工程中的类和系统类添加新的方法
作用:在类目中添加新的额方法及属性 和 在原类中添加方法及属性时一样的,都能够被类和类的子类调用,这样可以快速便利地维护和开发项目。
note:如何在类目中为原类添加新的方法和属性?
*/
Tool *tool = [Tool new];
//这是键值访问,既KVC
[tool setValue:@"Rick" forKey:@"_name"];
[tool setProperty2:@"property2"];
[tool function1];
[tool function2];
[tool function3];
MyClass *myClass = [MyClass new];
/*
由于几乎所有的类都继承于NSObject类(其余继承于NSProxy),由于NSObject的特殊性,所以NSObject的类目称为‘非正式协议’,创建一个NSObject的类目而不实现,称为‘创建一个非正式协议’。
*/
//-(bool)respondsToSelector:(SEL)aSelector;这个方法可以检查当前对象是否能够响应aSelector方法
if ([myClass respondsToSelector:@selector(test1)]) {
[myClass test1];
}
if ([myClass respondsToSelector:@selector(test2)]) {
[myClass test2];
}
#pragma mark~~~~~~~~~~~~~延展~~~~~~~~~~~~~~~~
[myClass setValue:@"我是延展的属性2" forKey:@"property3"];
if ([myClass respondsToSelector:@selector(test2)]) {
[myClass test2];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
创建一个Tool类
//
// Tool.h
// OC-09_01
//
// Created by Ibokan on 15/12/21.
// Copyright © 2015年 ibokan. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Tool : NSObject
{
NSString *_name;
}
//原类的属性
@property (nonatomic,strong)NSString *property;
//原类的方法
-(void)function1;
@end
#pragma mark~~~~~~~~~~~类目~~~~~~~~~~~
//在类目中为原类添加新的属性和方法
/*
类目就是为已存在的类添加新的方法,但是不能添加实例变量
类目的使用环境
1.类包含了很多个方法实现,而这些方法需要不同团队的成员变量来实现。
2.当你在使用基础类库中的类时,你不想继承这些类而指向添加一些方法时。
类目能实现上面需求,当然也有使用类目时需要注意的问题
1.类目可以访问原始类的实例变量,但不能添加实例变量,如果想添加实例变量,那就通过继承创建子类来实现。
2.类目可以重载原始类的方法,但是不推荐这么做,这样会覆盖掉原始类的方法,如果确实要重载,那就通过继承创建子类来实现。
3.和普通接口有所区别的是,在类目的实现文件中的实例方法只要你不去调用它你可以不用实现声明的所有方法。
*/
@interface Tool (ToolCategory)
@property (nonatomic,strong)NSString *property2;
//{
// NSString *_property2;
//
//}
-(void)function2;
//通过类目重载原始类的方法
-(void)function1;
@end
实现Tool类的属性和方法
//
// Tool.m
// OC-09_01
//
// Created by Ibokan on 15/12/21.
// Copyright © 2015年 ibokan. All rights reserved.
//
#import "Tool.h"
#import <objc/runtime.h>
@implementation Tool
-(void)function1
{
NSLog(@"I'am function1");
}
@end
@implementation Tool (ToolCategory)
/*
在一般情况下,我们是不能向Category添加属性的,只能添加方法,但有些情况下,我们确实需要向类目中添加属性,而且系统的API也有一些在Category添加属性的情况,那么着到底是怎么实现的呢?
ios运行时机制
ios运行时机制,简单来说,就是苹果为开发者提供的一套在运行时动态创建类,属性,方法的API,它是一套纯C语言的API,使用响应的API就可以通过Category给一个原本存在的类添加属性
*/
#pragma mark~~~~~~~~~~~~~~~合成类目中的属性
-(void)setProperty2:(NSString *)property2
{
/*
id object :给那个对象的属性赋值
const void *key :属性对应的key
id value:设置属性值为value
<#objc_AssociationPolicy policy#>:使用的策略,是一个枚举值,手机开发一般都选择NONATOMIC
如下取值:
OBJC_ASSOCIATION_ASSIGN //assign策略
OBJC_ASSOCIATION_RETAIN_NONATOMIC //retain策略
OBJC_ASSOCIATION_COPY_NONATOMIC //copy策略
OBJC_ASSOCIATION_RETAIN
OBJC_ASSOCIATION_COPY
*/
objc_setAssociatedObject(self,@selector(property2), property2, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)property2
{
return objc_getAssociatedObject(self, @selector(property2));
}
-(void)function2
{
//类目可以访问原始类的实例变量
NSLog(@"%@",_name);
NSLog(@"I'am function2");
NSLog(@"property2 = %@",[self property2]);
}
-(void)function1
{
NSLog(@"通过类目重载的function1");
}
@end
OC中的延展
//
// MyClass.m
// OC-09_01
//
// Created by Ibokan on 15/12/21.
// Copyright © 2015年 ibokan. All rights reserved.
//
#import "MyClass.h"
#import <objc/runtime.h>
#import "MyClass_MyClass_Extension.h"
@interface MyClass ()
@property (nonatomic,retain)NSString *property3;
-(void)textExtension;
@end
@implementation MyClass
#pragma mark~~~~~~~~~~~~~~~~延展~~~~~~~~~~~~~~~~~~
/*
延展
延展的作用就是定义自己的私有方法
形式和类目相同,不必新创建文件,只是把类目的interface文件放在你需要扩展的类的.m文件里
*/
-(void)test1
{
NSLog(@"I'am test1");
}
-(void)test2
{
NSLog(@"I‘am test2");
[self textExtension];
// [self setProperty3:@"我是延展属性"];
NSLog(@"%@",self.property3);
[self myClassExtenson2];
}
//延展
-(void)textExtension
{
NSLog(@"我是延展");
}
//oc运行时设置延展中的属性
-(void)setProperty3:(NSString *)property3
{
objc_setAssociatedObject(self, @selector(property3), property3, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)property3
{
return objc_getAssociatedObject(self, @selector(property3));
}
-(void)myClassExtenson2
{
NSLog(@"我是延展:MyClassExtension2");
}
@end
OC中的非正式协议
创建一个非正式协议
//
// NSObject+NsObjext_Category.h
// OC-09_01
//
// Created by Ibokan on 15/12/21.
// Copyright © 2015年 ibokan. All rights reserved.
//
#import <Foundation/Foundation.h>
//给NSObject添加一个类目,既非正式协议
@interface NSObject (NsObjext_Category)
-(void)test1;
-(void)test2;
@end