2

私はプロジェクト内でこれを使用しようとしています: 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 が呼び出されていないためUIApplicationDidBecomeActiveNotification、init メソッドで作成されているなどの通知がまだ呼び出されていることです。

私が見る限り、Permission Manager は作成され、参照されていないため、ぶらぶらしているだけです。

readPermsions の public メソッドは次のとおりです。

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

新しいインスタンスが作成され、別のメソッドが呼び出されてから、resultsBlock が返されます。私が知る限り、これを解放するものは何もありません。dealloc を呼び出すにはどうすればよいですか?

4

1 に答える 1

1

これNSNotificationCenterは、登録されているブロックを保持しているオブザーバー オブジェクトを保持しているためです。これにより、View Controller がキャプチャされ、割り当てが解除されなくなります。

ビュー コントローラーを解放できるようにする場合は__weak typeof(self) weakSelf = self;、ブロックの外側でビュー コントローラーへの弱参照 ( ) を作成し、ブロックweakSelfの内側で使用する必要があります。

また、オブザーバーを正しく削除していません。通知センター ブロック API を使用してオブザーバーを追加すると、オブザーバーとして実際に追加され、参照を保持して に渡す必要があるオブジェクトが返されますremoveObserver:

ブロックで監視する方法を使用しないことをお勧めします。これは、価値がある以上に管理上の問題が増えるためです。代わりにセレクターを取るものを使用してください。

于 2015-08-06T22:03:16.753 に答える