我正在尝试在项目中使用它: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?
答案 0 :(得分:1)
这是因为NSNotificationCenter
保留了观察者对象,该对象保留了向其注册的块,捕获了视图控制器并阻止其被释放。
如果您希望能够释放视图控制器,那么您应该在块外创建一个弱引用(__weak typeof(self) weakSelf = self;
)并在块内使用weakSelf
。
您也没有正确删除观察者。当您使用通知中心块api添加观察者时,它会返回一个对象,该对象实际上是作为观察者添加的对象,您需要保留引用并传递给removeObserver:
。
我建议不要使用该方法来观察一个块,因为它增加了更多的管理麻烦而不是它的价值。使用带选择器的那个。