通知不会导致dealloc被调用

我想在一个项目中使用这个: https : //github.com/zakkhoyt/VWWPermissionKit

我不太了解KVO /通知中心,所以我想发表一个问题。

基本上,Permission Manager的init和dealloc如下所示:

- (instancetype)init { self = [super init]; if (self) { [[NSNotificationCenter defaultCenter] addObserverForName:VWWPermissionNotificationsPromptAction object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { dispatch_async(dispatch_get_main_queue(), ^{ VWWPermission *permission = note.userInfo[VWWPermissionNotificationsPermissionKey]; [permission presentSystemPromtWithCompletionBlock:^{ dispatch_async(dispatch_get_main_queue(), ^{ [permission updatePermissionStatus]; if(permission.status == VWWPermissionStatusDenied){ [self.permissionsViewController displayDeniedAlertForPermission:permission]; } [self checkAllPermissionsSatisfied]; }); }]; }); }]; [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { dispatch_async(dispatch_get_main_queue(), ^{ [self readPermissions]; }); }]; } return self; } -(void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self]; } 

如果我想读取一组权限,我会这样调用:

 NSArray *permissionsToRead = @[ [VWWCoreLocationWhenInUsePermission permissionWithLabelText:nil], [VWWNotificationsPermission permissionWithLabelText:nil] ]; [VWWPermissionsManager readPermissions:permissionsToRead resultsBlock:^(NSArray *permissions) { // Do something with the result } }]; 

这一切工作正常。 问题是dealloc没有被调用,所以Notifications仍然被调用,例如在init方法中创build的UIApplicationDidBecomeActiveNotification

据我可以看到权限pipe理器创build和不引用,因此它只是挂起。

readPermssions的公共方法如下所示:

 +(void)readPermissions:(NSArray*)permissions resultsBlock:(VWWPermissionsManagerResultsBlock)resultsBlock{ VWWPermissionsManager *permissionsManager = [[self alloc]init]; [permissionsManager readPermissions:permissions resultsBlock:resultsBlock]; } 

创build一个新的实例并调用另一个方法,然后将resultsBlock返回。 据我所知,没有任何东西可以释放。 我怎么会得到dealloc被称为?

这是因为NSNotificationCenter保留了观察者对象,该对象保留了注册的块,捕获你的视图控制器并阻止它被释放。

如果你希望你的视图控制器能够被释放,那么你应该在块外部创build一个弱引用( __weak typeof(self) weakSelf = self; ),并在块内使用weakSelf

你也不能正确地移除观察者。 当您使用通知中心块api添加观察者时,它将返回一个对象,该对象实际上是作为观察者添加的,并且您需要保留引用并将其传递给removeObserver:

我build议只是不要用这个方法来观察,因为它增加了更多的pipe理麻烦而不值得。 使用取代select器的那个。