forKeyPath: "_placeholderLabel.textColor") 3、为UICollectionView添加headerView //备注:UICollectionView跟UITableView在设置...{ self.downIcon.image = UIImage.init(named: "ic_down_y") self.label.textColor...topIcon.image = UIImage.init(named:"ic_down_f") addSubview(topIcon) UIView.animate(withDuration...tabBar.backgroundImage = UIImage.init() 7、获取导航栏+状态栏的高度 func navigationBarHeight() -> Float {...opacity view.layer.shadowRadius = radius view.layer.shadowOffset = offset } 使用实例
在图中,warrior实例转发了一个negotiate消息到Diplomat实例中,执行Diplomat中的negotiate方法,结果看起来像是warrior实例执行了一个和Diplomat实例一样的...如果该方法返回非nil的对象,则使用该对象作为新的消息接收者。...// 为目标对象中被调用的方法返回一个NSMethodSignature实例 #warning 运行时系统要求在执行标准转发时实现这个方法 - (NSMethodSignature *)methodSignatureForSelector...,没有找到就返回nil。...( Method m ); // 获取描述方法参数和返回值类型的字符串 const char * method_getTypeEncoding ( Method m ); // 获取方法的返回值类型的字符串
本文就介绍如何自定义alertView,看完你就懂得制作属于自己的alertView了 一、创建DWAlert.swift 创建一个类名为在DWAlert.swift,在class DWAlert:...(named: "1.png"), for: .normal) cancleBtn.setImage(UIImage.init(named: "2.png"), for: .highlighted...方法中添加的backImageView背景蒙版 2、获取当前主窗口,并定义一个alertView的frame 3、利用UIView.animate对alertView进行动画操作。...里面实现,该方法会在当alertView即将加入主窗口时被系统自动调用,详情请看UIView不可不知的秘密 override func willMove(toSuperview newSuperview...五、使用DWAlert 在ViewController创建一个按钮,并添加一个点击事件ClickMe,在方法里面创建alertView @IBAction func ClickMe(_ sender:
pod引用 是因为WXStorageModule这个类是私有的 所以只能用源代码了 具体代码 添加引用 #import "WeexSDK.h" #import "WXStorageModule.h" 在AppDelegate...if let data = Data.init(base64Encoded: base64Str){ if let image = UIImage.init...imageName = ZJStringUtils.replace(url, replaceStr: "xcassets:", withStr: "") if let image = UIImage.init...(named: imageName){ completedBlock(image,nil,true) }...渲染的方法 func renderWeex(){ let storage = WXStorageModule.init(); storage.setItem("name", value:
class的实例方法替换成返回statedClass,也就是说把调用class时候的isa指向了statedClass了。...这种方式_class_addMethod返回的是nil。...; …… …… }复制代码 这一段是hook前的准备工作: 获取原始的selector 获取带有aspects_xxxx前缀的方法 替换selector 获取实例对象的容器objectContainer...这里会把stu1的study( )方法也还原了。因为remove方法这个操作是对整个类的所有实例都生效的。 要想每个实例还原各自的方法,不影响其他实例,上述这段代码删除即可。...举个例子,比如说在NSArray中用Aspects 去hook了objectAtIndex的方法,然后在NSMutableArray中Swizzling了objectAtIndex方法。
1.2 相关函数 //为一个实例对象添加一个关联对象,由于是C函数只能使用C字符串,这个key就是关联对象的名称,value为具体的关联对象的值,policy为关联对象策略,与我们自定义属性时设置的修饰符类似...以至于苹果发邮件禁止使用热修复时 整个JSPath的Issues被炸锅了。热修复主要做的是替换现有的方法,或者增加新方法,需要对消息发送和转发有一定的理解。...如果获取到,则直接转发给它。如果返回了nil,继续下面的动作。...如果 -methodSignatureForSelector: 返回 nil ,Runtime 则会发出 -doesNotRecognizeSelector: 消息,程序这时也就挂掉了。...处理用户登录 5.4Crash的防范 OC中容器类在空值nil 和数组越界都会直接导致我们app 的crash 我们一种处理方式是利用Category增加新方法中判断值是否为空或者越界,对于新工程我们使用大家约定使用容器的
; } 从上面可以看到,class类方法和实例方法都是获取当前Class也就是isa指针 实例方法调用时,通过对象的 isa 在类中获取方法的实现 类方法调用时,通过类的 isa 在元类中获取方法的实现...当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。然后在派生类的setter方法里实现通知机制。...简单而言:实例对象在被观察时,生成派生类,派生类在setter方法中valuewillchange方法和valuesdidchanged方法里发出通知,并且通过isa-swizzling,从而使实例对象成为派生类的对象...,所以实例对象在setter属性时可以产生通知。...(NSKeyValueCodingCatogery中实现的类方法,默认实现为返回YES) 3、如果没有找到成员变量,调用setValue:forUnderfinedKey: 获取值 valueForKey
就是在程序运行的过程中,有一套C语言级别的API,它把代码从OC转换成C 2、原理: OC是基于C,并添加了面向对象的特性,将很多静态语言在编译和链接时做的事放到了runtime运行时来处理 C:函数的调用在编译时就知道会调用哪个函数...OC:在编译的时候并不知道,只在正在运行时才会根据函数名称找到对应的函数 3、作用 获取属性、方法、成员变量、协议(包括私有的) 给分类动态添加属性、方法 字典转模型 拦截并替换方法 实现NSCoding...当对象的引用计数为0时会调用dealloc方法,此时会在weak表中搜索,将所有weak对象置为nil。...Key:对象内存地址 — value:n个weak对象 5、使用 替换ViewController生命周期方法 解决获取索引、添加、删除元素越界crash问题 防止按钮重复暴力点击 全局更换控件初始效果...App热修复 App异常加载占位图通用类封装 全局修改导航栏返回按钮 (去掉title) 以下是使用内容: `NSObject`的`Category`里实现方法替换,方便需要的类直接调用: // NSObject
实际上,它是在方法实现中访问消息接收者对象的实例变量的途径 而当方法中的 super 关键字接收到消息时,编译器会创建一个 objc_super 结构体: struct objc_super { id...获取方法地址 在 IMP 那节提到过可以避开消息绑定而直接获取方法的地址并调用方法。这种做法很少用,除非是需要持续大量重复调用某方法的极端情况,避开消息发送泛滥而直接调用该方法会更高效。...如果此方法返回 nil 或 self,则会进入消息转发机制(forwardInvocation:);否则将向返回的对象重新发送消息。 转发 当动态方法解析不作处理返回NO时,消息转发机制会被触发。...当一个类被编译时,实例变量的布局也就形成了,它表明访问类的实例变量的位置。...在健壮的实例变量下编译器生成的实例变量布局跟以前一样,但是当 runtime 系统检测到与超类有部分重叠时它会调整你新添加的实例变量的位移,那样你在子类中新添加的成员就被保护起来了 需要注意的是在健壮的实例变量下
实际上,它是在方法实现中访问消息接收者对象的实例变量的途径 而当方法中的 super 关键字接收到消息时,编译器会创建一个 objc_super 结构体: struct objc_super { id...获取方法地址 在 IMP 那节提到过可以避开消息绑定而直接获取方法的地址并调用方法。这种做法很少用,除非是需要持续大量重复调用某方法的极端情况,避开消息发送泛滥而直接调用该方法会更高效。...self,因为那样会死循环 转发 当动态方法解析不作处理返回NO时,消息转发机制会被触发。...当一个类被编译时,实例变量的布局也就形成了,它表明访问类的实例变量的位置。...在健壮的实例变量下编译器生成的实例变量布局跟以前一样,但是当 runtime 系统检测到与超类有部分重叠时它会调整你新添加的实例变量的位移,那样你在子类中新添加的成员就被保护起来了 需要注意的是在健壮的实例变量下
method-swizzling的含义是方法交换,其主要作用是在运行时将一个方法的实现替换成另一个方法的实现,这就是我们常说的iOS黑魔法, 在OC中就是利用method-swizzling实现AOP,...生成对应关系 如下图所示,交换前后的sel和IMP的对应关系 method-swizzling涉及的相关API 通过sel获取方法Method class_getInstanceMethod:获取实例方法...oriMethod) { // 在oriMethod为nil时,替换后将swizzledSEL复制一个不做任何事的空实现,代码如下: class_addMethod(cls...方法获取类方法 在调用class_addMethod和class_replaceMethod方法添加和替换时,需要传入的类是元类,元类可以通过object_getClass方法获取类的元类 //封装的method-swizzling...oriMethod) { // 避免动作没有意义 // 在oriMethod为nil时,替换后将swizzledSEL复制一个不做任何事的空实现,代码如下: class_addMethod
animated) } func setItemData(itemData:[String:String]) { leftImageView.image = UIImage.init...(named: itemData["image"]!)...= nil){ tableView.deselectRow(at: tableView.indexPathForSelectedRow!...; } ///获取随机正整数 static func randomNum(num:Int)->Int{ let randomNum = Int(arc4random_uniform...inset.bottom; let maximumOffset = size.height; //当currentOffset与maximumOffset的值相等时,
struct objc_object *id; 向object发送消息时,Runtime库会根据object的isa指针找到这个实例object所属于的类,然后在类的方法列表以及父类方法列表寻找对应的方法运行...如果有同名会返回NO,修改的话需要使用method_setImplementation // 获取实例方法 Method class_getInstanceMethod ( Class cls, SEL...Method中的接收消息对象参数和方法选择器参数 在Method中使用self关键字来引用实例本身,self的内容即接收消息的对象是在Method运行时被传入的同时还有方法选择器。...注意的是forwardInvocation:方法只有在消息接收对象无法正常响应消息时才被调用。...前面的消息转发很强大,但是需要能够修改对应类的源码,但是对于有些类无法修改其源码时又要更改其方法实现时可以使用Method Swizzling,通过重新映射方法来达到目的,但是跟消息转发比起来调试会困难
1.3获取某个类的实例变量 如果你还需要获取某个类的实例变量做什么操作的话,可以使用如下这几个API: // 获取实例变量数组 Ivar * class_copyIvarList(Class cls,...unsigned int *outCount) // 获取实例变量名称 const char * ivar_getName( Ivar ivar) // 获取实例变量类型 const char * ivar_getTypeEncoding...不能添加属性的根本原因是不会帮我们自动添加对象的实例变量,也不会帮我们生成set 和get方法,虽然set /get 方法可以自己实现,但是没有实例变量来存储数据。 ?...补充一个关联对象的使用场景: 你在使用AlertView 或者ActionSheet的时候,有没有很苦恼不能在点击的代理方法中方便的获取到Model对象呢?...除了在控制器中添加一个property 这种方式外; 我们也可以为AlertView 或者ActionSheet 添加一个关联对象,这样就可以在代理方法中方便的获取到Model 对象啦。
imageV = UIImageView.init(frame: CGRect.init(x: 30, y: 300, width: 80, height: 80)) imageV.image = UIImage.init...MyNewTableViewCell if cell == nil { //自定义cell使用此方法 cell = MyNewTableViewCell(style...} 在Swift中,创建tableViewCell的方法可以分为两种创建tableView时候注册和需要使用时手动创建。先聊聊创建tableView的时候直接注册cell: myTb?....register(MyNewTableViewCell.self, forCellReuseIdentifier: "myCell") 当注册了Cell之后,在没有可重用的Cell时会自动创建,并且不能在需要时手动创建...: "") // // 4 选中时的背景图片 // tabbarController.tabBar.selectionIndicatorImage = UIImage(named
Method Swizzling 方法的封装 由于这几种常见 Crash 的防护都需要用到 Method Swizzling 技术。...Unrecognized Selector 防护 4.1 unrecognized selector sent to instance(找不到对象方法的实现) 如果被调用的对象方法没有实现,那么程序在运行中调用该方法时...如果这一步方法返回 nil,则进入下一步。 消息重定向:Runtime 系统利用 methodSignatureForSelector: 方法获取函数的参数和返回值类型。...如果 methodSignatureForSelector: 返回 nil。则 Runtime 系统会发出 doesNotRecognizeSelector: 消息,程序也就崩溃了。...把消息转发给动态生成类的实例对象,由目标类动态创建的方法实现,这样 APP 就不会崩溃了。
b.调用forwardingTargetForSelector:方法,尝试找到一个能响应该消息的对象。如果获取到,则直接把消息转发给它,返回非 nil 对象。否则返回 nil ,继续下面的动作。...如果获取不到,则直接调用doesNotRecognizeSelector抛出异常。如果能获取,则返回非nil:创建一个 NSlnvocation 并传给forwardInvocation:。...d.调用forwardInvocation:方法,将第3步获取到的方法签名包装成 Invocation 传入,如何处理就在这里面了,并返回非ni。...答案是通过 isa 混写(isa-swizzling)。 23、若一个类有实例变量NSString *_foo,调用setValue:forKey:时,可以以foo还是_foo作为key? 都可以。...然而 KVO 在实现中使用了isa 混写( isa-swizzling),这个的确不是很容易发现:Apple 还重写、覆盖了-class方法并返回原来的类。
** 答:使用了isa混写技术(isa-swizzling) ** 3. 接着2追问,什么是isa-swizzling?...)cls{ unsigned int count; //获取方法列表 Method *methodList = class_copyMethodList(cls, &count...count; i++) { //获取方法 Method method = methodList[i]; NSString...=> 在NSKVONotifying_MNPerson的父类 - MNPerson里面窥探,(子类会调用父类的super方法) //伪代码 @implementation NSKVONotifying_MNPerson...人工智能翻译:使用称为isa-swizzling的技术实现自动键值观察...当观察者注册对象的属性时,观察对象的isa指针被修改,指向中间类而不是真正的类,让开发者只关心他需要关心的类(那些他自己创建出来的类
用法 先给要替换的方法的类添加一个Category,然后在Category中的+(void)load方法中添加Method Swizzling方法,我们用来替换的方法也写在这个Category中。...注意要点 Swizzling应该总在+load中执行 Swizzling应该总是在dispatch_once中执行 Swizzling在+load中执行时,不要调用[super load]。...思路:对NSArray的objectAtIndex:方法进行Swizzling,替换一个有处理逻辑的方法。但是,这时候还是有个问题,就是类簇的Swizzling没有那么简单。...所以如果想对NSArray进行Swizzling,必须获取到其“真身”进行Swizzling,直接对NSArray进行操作是无效的。...所以如果我们对NSArray类进行Swizzling操作其实只是对父类进行了操作,在NSArray内部会创建其他子类来执行操作,真正执行Swizzling操作的并不是NSArray自身,所以我们应该对其
Objective-C 提供了以下 API 来动态替换类方法或实例方法的实现: class_replaceMethod 替换类方法的定义 method_exchangeImplementations...当类中没有想替换的原方法时,该方法会调用class_addMethod来为该类增加一个新方法,也因为如此,class_replaceMethod在调用时需要传入types参数,而method_exchangeImplementations...method_setImplementation 最简单的用法,当仅仅需要为一个方法设置其实现方式时使用。 以上 3 个方法的源码在 这里,感兴趣的同学可以读一读。...应用一:拦截系统自带的方法调用Method Swizzling 一般是在load方法中进行,确保最先被调用。+load方法会在Appdelegate的方法之前执行,是最先执行的方法。...使用场景 Method Swizzling 可以重写某个方法而不用继承,同时还可以调用原先的实现。通常的做法是在category中添加一个方法(当然也可以是一个全新的class)。
领取专属 10元无门槛券
手把手带您无忧上云