hello,大家好,在老项目上都用的是UIalertview,最近项目上有个bug,是长时间不操作的话要登出处理,但画面上如有alertview的话,不会消失,会留在画面上。这个问题以前好处理,获取画面上alertview的引用,dismiss就ok了。但是呢,ios7后就获取不到了。详情看这个https://blog.csdn.net/xundh/article/details/46546739
项目里alertview很多很多。一个一个改能改到猴年马月去。后找到一个很方便的办法。
#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方法。做了一些处理。
在我的项目里就用+ (void)dismissAllVisibleAlertViews;这个静态方法dismiss画面上的alertview。各位有维护老项目的可参考参考,很实用。
至于swizzling的原理,百度上有很多。https://blog.csdn.net/yiyaaixuexi/article/details/9374411