不会调用dealloc的通知

时间:2015-08-06 21:53:23

标签: ios objective-c key-value-observing notificationcenter

我正在尝试在项目中使用它:https://github.com/zakkhoyt/VWWPermissionKit

我不太了解KVO / Notification Center,因此我发布了一个问题。

基本上,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方法中创建UIApplicationDidBecomeActiveNotification

据我所知,Permission Manager已创建且未被引用,因此它只是挂起。

readPermssions的公共方法如下:

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

创建一个新实例并调用另一个方法然后传回resultsBlock。据我所知,没有什么可以释放这个。我怎样才能得到dealloc?

1 个答案:

答案 0 :(得分:1)

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

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

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

我建议不要使用该方法来观察一个块,因为它增加了更多的管理麻烦而不是它的价值。使用带选择器的那个。