hello,你們好,在老項目上都用的是UIalertview,最近項目上有個bug,是長時間不操做的話要登出處理,但畫面上若有alertview的話,不會消失,會留在畫面上。這個問題之前好處理,獲取畫面上alertview的引用,dismiss就ok了。可是呢,ios7後就獲取不到了。詳情看這個https://blog.csdn.net/xundh/article/details/46546739ios
項目裏alertview不少不少。一個一個改能改到猴年馬月去。後找到一個很方便的辦法。spa
#import <UIKit/UIKit.h> @interface UIAlertView (Dismiss) + (void)dismissAllVisibleAlertViews; @end #import "UIAlertView+Dismiss.h" #import <objc/runtime.h> // see http://nshipster.com/method-swizzling/ static inline void swizzle(Class class, SEL originalSelector, SEL swizzledSelector) { Method originalMethod = class_getInstanceMethod(class, originalSelector); Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } } @implementation UIAlertView (Dismiss) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ swizzle([self class], @selector(show), @selector(replace_show)); swizzle([self class], @selector(dismissWithClickedButtonIndex:animated:), @selector(replace_dismissWithClickedButtonIndex:animated:)); }); } + (void)dismissAllVisibleAlertViews { NSMutableSet *tempset = [[NSMutableSet alloc] initWithSet:[[self visibleAlertViews] copy]]; //[[self visibleAlertViews] copy]; for (NSValue *value in tempset) { id val = value.nonretainedObjectValue; if ([val isKindOfClass: [UIAlertView class]]) { [val dismissWithClickedButtonIndex: 0 animated: NO]; } } [tempset removeAllObjects]; tempset = nil; } #pragma mark - Method Swizzling - (void)replace_show { [self replace_show]; [[self.class visibleAlertViews] addObject: [NSValue valueWithNonretainedObject: self]]; } - (void)replace_dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { //[[self.class visibleAlertViews] removeObject: [NSValue valueWithNonretainedObject: self]]; [self replace_dismissWithClickedButtonIndex: buttonIndex animated: animated]; NSLog(@">>>>>>>xxx_dismissWithClickedButtonIndex"); [[self.class visibleAlertViews] removeObject: [NSValue valueWithNonretainedObject: self]]; } #pragma mark - Cache + (NSMutableSet *)visibleAlertViews { static NSMutableSet *views = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ views = [NSMutableSet new]; }); return views; } @end
就是這個了。運行時替換的alertview的show和dismiss方法。作了一些處理。.net
在個人項目裏就用+ (void)dismissAllVisibleAlertViews;這個靜態方法dismiss畫面上的alertview。各位有維護老項目的可參考參考,很實用。code
至於swizzling的原理,百度上有不少。https://blog.csdn.net/yiyaaixuexi/article/details/9374411blog