我有两个类,一个是基类,另一个是子类。在基类中,我添加了一个通知,当应用程序进入后台时将触发该通知。但有些应用程序在执行handleAppBackground
方法后崩溃了。我想它必须对子类实例做一些事情,因为当我从appDelegate中删除子类实例时,它不会崩溃。
#import <Foundation/Foundation.h>
@interface BaseClass : NSObject
+(BaseClass *) sharedManager;
- (void) handleAppBackground;
@end
实施文件
#import "BaseClass.h"
@implementation BaseClass
- (instancetype) init{
if(self = [super init]){
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
return self;
}
+(BaseClass *) sharedManager{
static BaseClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[BaseClass alloc] init];
});
return sharedInstance;
}
- (void) handleAppBackground{
NSLog(@"Here");
}
@end
SubClass是标题
#import <Foundation/Foundation.h>
#import "BaseClass.h"
@interface SubClass1 : BaseClass
-(SubClass1 *) init;
-(void) method1;
@end
,实施是
#import "SubClass1.h"
@implementation SubClass1
-(SubClass1 *) init{
if(self = [super init]){
}
return self;
}
-(void) method1{
NSLog(@"Called in SubClass1");
}
@end
并在appDidFinnishLaunching
中- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[BaseClass sharedManager];
SubClass1 *class1 = [[SubClass1 alloc] init];
[class1 method1];
// Override point for customization after application launch.
return YES;
}
这是崩溃日志中的任何帮助
thread #1: tid = 0x31435, 0x015740e6 libobjc.A.dylib`lookUpImpOrForward + 59, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x0)
frame #0: 0x015740e6 libobjc.A.dylib`lookUpImpOrForward + 59
frame #1: 0x0157405c libobjc.A.dylib`lookUpImpOrNil + 62
frame #2: 0x0156b84a libobjc.A.dylib`class_respondsToSelector_inst + 65
frame #3: 0x0156b801 libobjc.A.dylib`class_respondsToSelector + 32
frame #4: 0x017dd4cb CoreFoundation`___forwarding___ + 955
frame #5: 0x017dd0ee CoreFoundation`__forwarding_prep_0___ + 14
frame #6: 0x0123f049 Foundation`__57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40
frame #7: 0x01848f04 CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
frame #8: 0x017a0efb CoreFoundation`_CFXNotificationPost + 2859
frame #9: 0x01178e41 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 98
frame #10: 0x002334b3 UIKit`-[UIApplication _handleApplicationSuspend:eventInfo:] + 817
frame #11: 0x00240193 UIKit`-[UIApplication handleEvent:withNewEvent:] + 4030
frame #12: 0x00240555 UIKit`-[UIApplication sendEvent:] + 85
frame #13: 0x0022d250 UIKit`_UIApplicationHandleEvent + 683
frame #14: 0x037e2f02 GraphicsServices`_PurpleEventCallback + 776
frame #15: 0x037e2a0d GraphicsServices`PurpleEventCallback + 46
frame #16: 0x01768ca5 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
frame #17: 0x017689db CoreFoundation`__CFRunLoopDoSource1 + 523
frame #18: 0x0179368c CoreFoundation`__CFRunLoopRun + 2156
frame #19: 0x017929d3 CoreFoundation`CFRunLoopRunSpecific + 467
frame #20: 0x017927eb CoreFoundation`CFRunLoopRunInMode + 123
frame #21: 0x037e15ee GraphicsServices`GSEventRunModal + 192
frame #22: 0x037e142b GraphicsServices`GSEventRun + 104
frame #23: 0x0022cf9b UIKit`UIApplicationMain + 1225
* frame #24: 0x00002a2d TestSubclass`main(argc=1, argv=0xbfffed60) + 141 at main.m:16
答案 0 :(得分:1)
您遇到的问题是:致电:
SubClass1 *class1 = [[SubClass1 alloc] init];
您将class1注册为观察者,但在该行之后:
[class1 method1];
该对象被释放,当您转到后台时,NSNotificationCenter会尝试在该类(已解除分配)上调用方法handleAppBackground
导致压缩的原因。
要解决此问题,只需将此类删除为观察者,将此方法添加到SubClass1.m:
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
答案 1 :(得分:0)
您的应用看起来崩溃了,因为它无法找到您分配给通知的选择器。
在你的情况下,导致它的原因是你没有将SubClass1的类对象设置为AppDelegate的iVar。
SubClass1 * class1
因此,在didFinishLaunchingWithOptions方法之后释放对象,当应用程序转到后台时,由于对象被解除分配,观察者无法找到选择器。
在您的示例中,如果您将AppDelegae.m代码更改为
@interface AppDelegate()
{
SubClass1 *class1;
}
@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[BaseClass sharedManager];
class1 = [[SubClass1 alloc] init];
[class1 method1];
.......
}
并且在释放SubClass1时不要忘记删除观察者
SubClass1.m
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
所以这基本上是一个记忆问题。