导致不调用dealloc的通知 [英] Notifications causing no dealloc to be called

查看:119
本文介绍了导致不调用dealloc的通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to use this within a project: https://github.com/zakkhoyt/VWWPermissionKit

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

I do not understand KVO/Notification Center as much as I'd like so posting a question.

基本上,权限管理器的init和dealloc如下所示:

Basically the init and dealloc for the Permission Manager look like this:

- (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];
}

如果我想阅读一组权限,可以这样称呼:

If I want to read a set of permissions I would call this:

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

一切正常.问题在于未调用dealloc,因此仍在调用通知,例如在init方法中创建的UIApplicationDidBecomeActiveNotification.

This all works fine. The issue is that the dealloc is not being called, therefore the Notifications are still being called such as the UIApplicationDidBecomeActiveNotification being created in the init method.

据我所知,权限管理器已创建但未被引用,因此它只是在周围徘徊.

As far as I can see the Permission Manager is created and not referenced and therefore it just hangs around.

readPermssions的公共方法如下:

The public method for the readPermssions is as follows:

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

创建一个新实例,然后调用另一个方法,然后将resultsBlock传回.据我所知,没有什么可以解决这个问题的.我该如何调用dealloc?

A new instance is created and another method is called then passes the resultsBlock back. There is nothing that releases this as far as I can tell. How would I get the dealloc to be called?

推荐答案

这是因为NSNotificationCenter保留了观察者对象,该观察者对象保留了向其注册的块,从而捕获了您的视图控制器并阻止了它的出现.释放.

It's because NSNotificationCenter is retaining the observer object, which is retaining the block that is registered with it, which is capturing your view controller and preventing it from being deallocated.

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

If you want your view controller to be able to be released then you should create a weak reference (__weak typeof(self) weakSelf = self;) to it outside the block and use weakSelf inside the block.

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

You also aren't removing the observer correctly. When you add an observer using the notification center block api it returns an object which is what it is actually adding as the observer and which you need to keep a reference to and pass to removeObserver:.

我建议您不要使用该方法进行块观察,因为这会增加管理上的麻烦,而不是值得的.改用带有选择器的那个.

I would suggest just not using the method to observe with a block since it adds more management trouble than it's worth. Use the one that takes a selector instead.

这篇关于导致不调用dealloc的通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆