通知不会导致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器的那个。
- 与CALayers CAAnimation偶尔创build闪烁的animation(包括video)
- 是否有任何工作algorithm来计算所有iOS设备(有或没有M7芯片)的步骤?
- RubyMotion重新加载UITableView的部分
- iOS从本地通知打开页面
- 改变UIView的边界并让UICollisionBehavior对它作出反应
- 一个更好的方法来animation调整UIView和子视图的大小?
- 使用networking连接一次下载一个文件
- 在代码中,基于交换机,在运行时将ui web视图添加到ui web视图
- registerUserNotificationSettings不显示提示iOS 8