項(xiàng)目里需要增加強(qiáng)制更新功能,此時(shí)使用的是系統(tǒng)的UIAlertController,結(jié)果點(diǎn)擊跳轉(zhuǎn)到App Store之后,彈框就消失了,這是因?yàn)橄到y(tǒng)默認(rèn)會(huì)自己dismiss,所以需要自己加個(gè)變量可以控制是否dismiss。
@dynamicft_rejectDismiss;
- (void)setFt_rejectDismiss:(BOOL)ft_rejectDismiss {
objc_setAssociatedObject(self, @selector(ft_rejectDismiss), @(ft_rejectDismiss), OBJC_ASSOCIATION_ASSIGN);
}
- (BOOL)ft_rejectDismiss {
return [(NSNumber *)objc_getAssociatedObject(self, _cmd) boolValue];
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Classclass = [selfclass];
SEL originalSelector = NSSelectorFromString(@"_dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:dismissCompletion:");
SELswizzledSelector =@selector(ft_dismissAnimated:
triggeringAction:
triggeredByPopoverDimmingView:
dismissCompletion:);
MethodoriginalMethod =class_getInstanceMethod(class, originalSelector);
MethodswizzledMethod =class_getInstanceMethod(class, swizzledSelector);
// 動(dòng)態(tài)添加方法,如果類(lèi)中不存在這個(gè)方法的實(shí)現(xiàn),則添加成功
// 這里 UIAlertController 類(lèi)中存在 originalMethod,所以添加是失敗的
BOOLdidAddMethod =class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if(didAddMethod) {
// 如果添加成功,則用 originalMethod 替換添加的空方法 originalMethod
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
}else{
// 交換兩個(gè)方法的實(shí)現(xiàn)
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)ft_dismissAnimated:(BOOL)animation
triggeringAction:(UIAlertAction*)action
triggeredByPopoverDimmingView:(id)view
dismissCompletion:(id)handler {
// 如果點(diǎn)擊“取消”按鈕或者允許彈框 dismiss,就調(diào)用原來(lái)的方法(originalMethod)
// 因?yàn)橐呀?jīng)交換了兩個(gè)方法的實(shí)現(xiàn),所以其實(shí)是調(diào)用 swizzledMethod
// 所以這里并不會(huì)出現(xiàn)循環(huán)調(diào)用
// 否則就忽略原來(lái)的方法(originalMethod),直接下一步,掉用后面的方法
if (action.style == UIAlertActionStyleCancel || self.ft_rejectDismiss == NO) {
[self ft_dismissAnimated:animation
triggeringAction:action
triggeredByPopoverDimmingView:view
dismissCompletion:handler];
}else{
SEL invokeHandler = NSSelectorFromString(@"_invokeHandlersForAction:");
// 這里如果使用 performSelector 來(lái)調(diào) invokeHandler 這個(gè)方法
// [self performSelector:invokeHandler withObject:action];
// 會(huì)報(bào) "PerformSelector may cause a leak because its selector is unknown" 的警告
// 為消除警告,用下面的方法
IMPimp = [selfmethodForSelector:invokeHandler];
void(*func)(id,SEL,UIAlertAction*) = (void*)imp;
func(self, invokeHandler, action);
}
}