kvc error

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x7fb3ddd0ba80 of class BtnViewController was deallocated while key value observers were still registered with it.

 

被关注的对象的生命周期不足!

转载于:https://www.cnblogs.com/code-Officer/p/6305445.html

#import <Foundation/Foundation.h> #import <Security/Security.h> #import <UIKit/UIKit.h> #import <CommonCrypto/CommonDigest.h> @interface GlobalSecurityManager : NSObject + (void)performComprehensiveSecurityScan; + (BOOL)validateSecureInput:(NSString *)input; + (void)handleSecurityException:(NSException *)exception; @end @implementation GlobalSecurityManager // 执行全局安全扫描 + (void)performComprehensiveSecurityScan { @try { // 1. 设备安全检测 [self checkDeviceSecurity]; // 2. 应用完整性验证 [self verifyAppIntegrity]; // 3. 数据安全防护 [self secureDataStorage]; // 4. 网络安全检查 [self checkNetworkSecurity]; NSLog(@"✅ Global security scan completed successfully"); } @catch (NSException *exception) { [self handleSecurityException:exception]; } @finally { [self logSecurityEvent:@"Security scan executed"]; } } #pragma mark - 安全检测方法 // 设备安全检测(越狱/调试) + (void)checkDeviceSecurity { // 越狱检测 if ([self isDeviceJailbroken]) { [NSException raise:@"DeviceCompromised" format:@"Jailbreak detected. Security compromised"]; } // 调试器检测 if ([self isDebuggerAttached]) { [NSException raise:@"DebuggerDetected" format:@"Debugger attached. Potential security breach"]; } // 屏幕截图检测 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(detectScreenshot) name:UIApplicationUserDidTakeScreenshotNotification object:nil]; } // 应用完整性验证 + (void)verifyAppIntegrity { // 1. 签名验证 if (![self verifyCodeSignature]) { [NSException raise:@"InvalidSignature" format:@"Application signature verification failed"]; } // 2. 篡改检测 if ([self isAppTampered]) { [NSException raise:@"AppTampered" format:@"Application binary has been modified"]; } } // 数据安全防护 + (void)secureDataStorage { // Keychain安全配置 NSDictionary *keychainQuery = @{ (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, (id)kSecUseAuthenticationUI: (id)kSecUseAuthenticationUIFail }; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL); if (status != errSecSuccess && status != errSecDuplicateItem) { [NSException raise:@"KeychainError" format:@"Keychain security configuration failed with status: %d", status]; } } // 网络安全检查 + (void)checkNetworkSecurity { // SSL证书锁定 [self enforceSSLPinning]; // 网络配置检查 if (![self verifyNetworkSecuritySettings]) { [NSException raise:@"NetworkConfigError" format:@"Insecure network configuration detected"]; } } #pragma mark - 安全检测实现 // 越狱检测 + (BOOL)isDeviceJailbroken { // 检查越狱常见路径 NSArray *jailbreakIndicators = @[ @"/Applications/Cydia.app", @"/usr/sbin/sshd", @"/bin/bash", @"/etc/apt" ]; for (NSString *path in jailbreakIndicators) { if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { return YES; } } // 尝试写入系统目录 NSString *testPath = @"/private/jailbreak_test.txt"; NSError *error; [@"test" writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:&error]; if (!error) { [[NSFileManager defaultManager] removeItemAtPath:testPath error:nil]; return YES; } return NO; } // 调试器检测 + (BOOL)isDebuggerAttached { struct kinfo_proc info; size_t info_size = sizeof(info); int name[4]; name[0] = CTL_KERN; name[1] = KERN_PROC; name[2] = KERN_PROC_PID; name[3] = getpid(); if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) { NSLog(@"sysctl failed: %s", strerror(errno)); return NO; } return (info.kp_proc.p_flag & P_TRACED) != 0; } // 签名验证(解决引用[3]的证书问题) + (BOOL)verifyCodeSignature { NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; SecStaticCodeRef staticCode = NULL; OSStatus status = SecStaticCodeCreateWithPath((__bridge CFURLRef)[NSURL fileURLWithPath:bundlePath], kSecCSDefaultFlags, &staticCode); if (status != errSecSuccess) { return NO; } // 验证签名 status = SecStaticCodeCheckValidity(staticCode, kSecCSDefaultFlags, NULL); CFRelease(staticCode); return (status == errSecSuccess); } #pragma mark - 错误处理(解决引用[1][2]的KVC问题) // 安全设置属性值(避免setValue:forUndefinedKey错误) + (void)safeSetValue:(id)value forKey:(NSString *)key onObject:(id)object { if (!object || !key) return; @try { // 检查对象是否响应选择器 if ([object respondsToSelector:NSSelectorFromString(key)]) { [object setValue:value forKey:key]; } // 检查嵌套控制器(解决引用[1]的问题) else if ([object isKindOfClass:[UINavigationController class]]) { UIViewController *topVC = [(UINavigationController *)object topViewController]; if ([topVC respondsToSelector:NSSelectorFromString(key)]) { [topVC setValue:value forKey:key]; } } } @catch (NSException *exception) { [self handleKeyValueException:exception forObject:object key:key]; } } // 处理KVC异常 + (void)handleKeyValueException:(NSException *)exception forObject:(id)object key:(NSString *)key { NSString *errorDetail = [NSString stringWithFormat:@"KVC Error on %@: %@", NSStringFromClass([object class]), exception.reason]; [self logSecurityEvent:errorDetail]; // 安全恢复措施 if ([exception.name isEqualToString:@"NSUnknownKeyException"]) { @try { if ([object respondsToSelector:@selector(setValue:forUndefinedKey:)]) { [object setValue:nil forUndefinedKey:key]; } } @catch (NSException *secondaryException) { [self handleSecurityException:secondaryException]; } } } // 全局异常处理 + (void)handleSecurityException:(NSException *)exception { // 1. 安全日志记录 [self logSecurityEvent:[NSString stringWithFormat:@"CRITICAL: %@", exception.reason]]; // 2. 清除敏感数据 [self purgeSensitiveData]; // 3. 安全恢复或退出 if ([exception.name isEqualToString:@"DeviceCompromised"] || [exception.name isEqualToString:@"AppTampered"]) { // 严重安全问题,安全退出 [self showSecurityAlert:exception.reason]; exit(EXIT_FAILURE); } else { // 可恢复错误,通知用户 [self showSecurityAlert:@"Security issue detected. Some features may be limited"]; } } #pragma mark - 辅助方法 // 显示安全警告 + (void)showSecurityAlert:(NSString *)message { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Security Alert" message:message preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController; [rootVC presentViewController:alert animated:YES completion:nil]; }); } // 清除敏感数据 + (void)purgeSensitiveData { // 清除用户数据 [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]]; // 清除Keychain数据 NSDictionary *query = @{(id)kSecClass: (id)kSecClassGenericPassword}; SecItemDelete((__bridge CFDictionaryRef)query); } // 安全日志记录 + (void)logSecurityEvent:(NSString *)event { NSLog(@"🔒 SECURITY LOG: %@", event); // 实际应用中应发送到安全服务器 } @end // 在AppDelegate中调用 @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 执行全局安全扫描 [GlobalSecurityManager performComprehensiveSecurityScan]; // 安全设置示例(避免引用[1][2]的错误) DetailViewController *detailVC = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"DetailVC"]; [GlobalSecurityManager safeSetValue:self.selectedItem forKey:@"detailItem" onObject:detailVC]; return YES; } @end 结合修复
最新发布
08-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值