0

IOS 6.1

そこにないキーと値のペアに対して removeObserver の例外を取得すると、KVP を持つクラスが removeObserver 呼び出しからカウントを取得し、追加の保持カウントを取得することに気付きました。

以下は、これを証明するテストコードです。また、これを修正するブリッジ リリースもあります。

どんなコメントでも歓迎....

#import "ViewController.h"
#import "ClassA.h"

@interface ViewController ()

@property (strong, nonatomic) ClassA* classA;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];    
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"radarOn"])
    {
        NSLog(@"--- here in radaron");
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Here" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }
}

- (IBAction)CreateClassAAction:(id)sender
{
    self.classA = [[ClassA alloc] init];
}

- (IBAction)SendNotificationAction:(id)sender
{
    self.classA.radarOn = ! self.classA.radarOn;
}

- (IBAction)ClearKVPAction:(id)sender
{
    @try
    {
        [self.classA removeObserver:self forKeyPath:@"radarOn"];
    }
    @catch (NSException *exception)
    {
        NSString *s = [NSString stringWithFormat:@"Exception ClassA Retain Count %ld %@", CFGetRetainCount((__bridge CFTypeRef)(self.classA)), exception.description];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:s delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        // this will let the class release
        // CFBridgingRelease((__bridge CFTypeRef)(self.classA));
    }
}

- (IBAction)AddKVPAction:(id)sender
{
  [self.classA addObserver:self forKeyPath:@"radarOn" options:NSKeyValueObservingOptionNew context:nil];
}

@end

#import <Foundation/Foundation.h>

@interface ClassA : NSObject

@property (nonatomic, assign) BOOL radarOn;

@end

#import "ClassA.h"

@implementation ClassA

- (void) dealloc
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"ClassA Dealloc" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}

@end
4

2 に答える 2

0

このようなコードは機能しているようです...(余分な保持はありません)

- (IBAction)ClearKVPAction:(id)sender
{
    @try
    {
        [_classA removeObserver:self forKeyPath:@"radarOn"];
    }
    @catch (NSException *exception)
    {
    }  
}

または

- (IBAction)ClearKVPAction:(id)sender
{
    ClassA* temp = self.classA;
    @try
    {
        [temp removeObserver:self forKeyPath:@"radarOn"];
    }
    @catch (NSException *exception)
    {
    }  
}

または

問題の .m ファイルに -fobjc-arc-exceptions を追加します。

于 2013-07-03T19:22:08.050 に答える