首先创建一个数组的分类
+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL safeSel=@selector(safeObjectAtIndex:);
SEL unsafeSel=@selector(objectAtIndex:);
Class myClass = NSClassFromString(@"__NSArrayI");
Method safeMethod=class_getInstanceMethod (myClass, safeSel);
//Method 是返回的方法的地址
Method unsafeMethod=class_getInstanceMethod (myClass, unsafeSel);
//将A方法 和 B方法互换的函数 method_exchangeImplementations(Method 1, Method 2);
method_exchangeImplementations(unsafeMethod, safeMethod);
});
}
-(id)safeObjectAtIndex:(NSUInteger)index{
if (index>(self.count-1)) {
NSAssert(NO, @"beyond the boundary");
return nil;
} else{
return [self safeObjectAtIndex:index];
//这里不会造成循环 上面已经将safeObjectAtIndex 和系统的方法进行互换 如果在 外面调用 SEL unsafeSel=@selector(objectAtIndex:); 方法的时候会互换到 safeObjectAtIndex 方法中 很容易理解吧
}
方法互换 我们可以在mjRefresh 中看到这个代码
第一个是互换 对象方法 第二个是互换类方法 是不是很好玩
这样我们可以进行更多的操作
+ (void)exchangeInstanceMethod1:(SEL)method1 method2:(SEL)method2
{
method_exchangeImplementations(class_getInstanceMethod(self, method1), class_getInstanceMethod(self, method2));
}
+ (void)exchangeClassMethod1:(SEL)method1 method2:(SEL)method2
{
method_exchangeImplementations(class_getClassMethod(self, method1), class_getClassMethod(self, method2));
}
class_getClassMethod(self, method1) 获取 class 方法
class_getInstanceMethod(self, method1) 获取对象方法 通过SEL 以及 class
下面我们来看一下 runtime 中的拓展属性时候注意的地方 为了实现KVO能够监听该属性的改变在调用之前首先调用了
willChangeValueForKey:
didChangeValueForKey:
两个方法 实现真正意义上的 拓展属性 可监听值的改变性
截图自UIScrollView+MJRefreshstatic const char MJRefreshHeaderKey = '\0'; 我感觉如同 从字典中找相关的内容 查字典的感觉
OBJC_ASSOCIATION_ASSIGN 0 相当于 weak 如果对象消失 该属性也会消失
OBJC_ASSOCIATION_RETAIN_NONATOMIC 1
The association is not made atomically 这个是我们的 no atomically strong 属性使用
个人愚见 忘请指正
设置block类型的属性 怎么设置 呢,其实我们想给我们呢 就如同我们写一个创建按钮的方法然后又能够在点击的时候像是 以block的方式类似以mj 刷新似得那样呢
我们也可以写一个button的拓展block 属性 来做类似的操作
网友评论