iOS7兼容版本:
我做的,存儲在init()方法的所有實例的類接口。
我知道這是一種非常低效的方式。
#import <objc/runtime.h>
#import <objc/message.h>
@interface UIAlertView(EnumView)
+ (void)startInstanceMonitor;
+ (void)stopInstanceMonitor;
+ (void)dismissAll;
@end
@implementation UIAlertView(EnumView)
static BOOL _isInstanceMonitorStarted = NO;
+ (NSMutableArray *)instances
{
static NSMutableArray *array = nil;
if (array == nil)
array = [NSMutableArray array];
return array;
}
- (void)_newInit
{
[[UIAlertView instances] addObject:[NSValue valueWithNonretainedObject:self]];
[self _oldInit];
}
- (void)_oldInit
{
// dummy method for storing original init IMP.
}
- (void)_newDealloc
{
[[UIAlertView instances] removeObject:[NSValue valueWithNonretainedObject:self]];
[self _oldDealloc];
}
- (void)_oldDealloc
{
// dummy method for storing original dealloc IMP.
}
static void replaceMethod(Class c, SEL old, SEL new)
{
Method newMethod = class_getInstanceMethod(c, new);
class_replaceMethod(c, old, method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
}
+ (void)startInstanceMonitor
{
if (!_isInstanceMonitorStarted) {
_isInstanceMonitorStarted = YES;
replaceMethod(UIAlertView.class, @selector(_oldInit), @selector(init));
replaceMethod(UIAlertView.class, @selector(init), @selector(_newInit));
replaceMethod(UIAlertView.class, @selector(_oldDealloc), NSSelectorFromString(@"dealloc"));
replaceMethod(UIAlertView.class, NSSelectorFromString(@"dealloc"), @selector(_newDealloc));
}
}
+ (void)stopInstanceMonitor
{
if (_isInstanceMonitorStarted) {
_isInstanceMonitorStarted = NO;
replaceMethod(UIAlertView.class, @selector(init), @selector(_oldInit));
replaceMethod(UIAlertView.class, NSSelectorFromString(@"dealloc"), @selector(_oldDealloc));
}
}
+ (void)dismissAll
{
for (NSValue *value in [UIAlertView instances]) {
UIAlertView *view = [value nonretainedObjectValue];
if ([view isVisible]) {
[view dismissWithClickedButtonIndex:view.cancelButtonIndex animated:NO];
}
}
}
@end
在使用UIAlertView之前啓動實例監視。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//...
//...
[UIAlertView startInstanceMonitor];
return YES;
}
呼叫dismissAll在顯示另一個之前。
[UIAlertView dismissAll];
如果您可以控制所有UIAlertViews,使用單例模式會更好。
但在我的情況下,我需要這個代碼在UIWebView中關閉JavaScript警報對話框。
工作得很好。謝謝:) – 2011-03-23 03:24:31
它看起來像這不適用於iOS6。 – erkanyildiz 2012-09-17 16:05:15
...這就是爲什麼迭代私有內部視圖結構是一個脆弱的過程。 – 2013-05-17 14:27:08