这几天,项目第一阶段进入收尾和测试阶段了,之前测试时,所有的设备都是iOS9的,这次用iOS8测试时,自定义封装的弹出框出现了响应代理事件和代理传值时崩溃的情况,用iOS7也是这样。首先,我检查了代码,发现没有iOS9以后的代码,说明代码的版本兼容本身是没有问题。
先上一段代码:
自定义弹出框.h文件
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, AlertState){
AlertStateDefault,//默认状态
AlertStateCompleteShake,//摇加息已完成
AlertStateSystemSuccess,//黑色弹出框代理回调必须,配合-(void)alertViewDidHidden;
};
@class AlterView;
@protocol AlterViewDelegate <NSObject>
@optional
//左边按钮代理方法(默认隐藏弹出框)
-(void)alertLeftButtonActionWithButton:(UIButton *)button Alert:(AlterView *)alert;
//右边按钮代理方法(默认隐藏弹出框)
-(void)alertRightButtonActionWithButton:(UIButton *)button Alert:(AlterView *)alert;
//传递字符串
-(void)alertForSendMessage:(NSString *)message;
//已隐藏
-(void)alertViewDidHidden;
@end
@interface AlterView : UIView
@property (nonatomic, weak) id<AlterViewDelegate>delegate;
@property (nonatomic) AlertState alertState;
自定义弹出框.m文件
#pragma mark 隐藏弹出框
-(void)hiddenAlert{
[_darkView removeFromSuperview];
[self removeSubviews];
[self removeFromSuperview];
if (self.alertState != AlertStateDefault) {
[_delegate alertViewDidHidden];
}
}
#pragma mark 左边按钮被点击
-(void)leftButtonClicketed:(UIButton *)button{
[self hiddenAlert];
// if (self.alertState != YWAlertStateDefault) {
[_delegate alertLeftButtonActionWithButton:button Alert:self];
// }
}
#pragma mark 右边按钮被点击
-(void)rightButtonClicketed:(UIButton *)button{
[self hiddenAlert];
[_delegate alertRightButtonActionWithButton:button Alert:self];
}
控制器中的代码
-(void)alertLeftButtonActionWithButton:(UIButton *)button Alert:(AlterView *)alert{
if (alert.tag == 679) {
[self startAccelerometer];
}
if ([button.currentTitle isEqualToString:@"XXX"]) {
self.tabBarController.selectedIndex = 1;
}
}
-(void)alertViewDidHidden{
}
-(void)alertRightButtonActionWithButton:(UIButton *)button Alert:(AlterView *)alert{
if (alert.tag == 679) {
self.tabBarController.selectedIndex = 1;
}else if (alert.tag == 678){
ShareViewController * shareVC = [[ShareViewController alloc] init];
[self.navigationController pushViewController:shareVC animated:YES];
}
}
接着,我用Xcode链接iOS8设备进行真机调试,结果崩了
从Xcode给的提示看,应该和内存有关,是循环引用了?还是提前释放了呢?于是我把Enable Zombie Objects勾上
然后再运行,于是Xcode帮我锁定了这个崩溃的元凶的地址,而且告诉我是提前释放的内存问题
既然能锁定内存地址,后面的事就好办了,只要找这个内存地址里是谁,就能解决问题,于是,我在代理方法的执行顺序上打断点
从我这两张截图可知,是自定义弹出框本身被提前释放了,而且也锁定了是[self hiddenAlert]这个方法里面提前释放了。在这个方法中执行了[self removeFromSuperview],使自定义弹出框本身被释放,然后再去执行代理方法,这时的弹出框已经是nil,所以造成了崩溃。
原因找到了,于是后面就好解决了,但是问题又来了,为什么iOS9中可以正常运行,但是iOS8以下就不可以呢。网上搜素了很久都没有找答案,我只能把这个问题暂时归结为代理传值在iOS9与之前版本的区别。如果有大牛可以帮我解答这个问题,欢迎留言