0

次のようなボタンでアラートを呼び出したいときに便利なクラスがあります。

- (IBAction)test:(id)sender {
    [MyAlertView showWithTitle:@"test" withCallBackBlock:^(int value){
        NSLog(@"Button Pressed %i", value); 
    }];
}

クラスは非常に単純です。

    @implementation MyAlertView
@synthesize callBackBlock = _callBackBlock, internalCallBackBlock = _internalCallBackBlock;

-(void)showWithTitle:(NSString *)title withCallBackBlock:(CallBackBlock )callBackBlock internalCallBackBlock:(CallBackBlock )internalCallBackBlock{
    self.callBackBlock = callBackBlock;
    self.internalCallBackBlock = internalCallBackBlock;

    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:title delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK" , nil];
        [alertView show];
        [alertView autorelease];
    });

}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (_callBackBlock) {
        _callBackBlock(buttonIndex);
    }

    if (_internalCallBackBlock) {
        _internalCallBackBlock(buttonIndex);
    }
}


-(void)dealloc{
    Block_release(_callBackBlock);
    Block_release(_internalCallBackBlock);
    [super dealloc];
}


+(void)showWithTitle:(NSString *)title withCallBackBlock:(CallBackBlock )callBackBlock{
    __block MyAlertView *alert = [[MyAlertView alloc]init];
    [alert showWithTitle:title withCallBackBlock:callBackBlock internalCallBackBlock:^(int value){
        [alert autorelease];
    }];

}
@end

シミュレーターでプロファイリングしましたが、リークもゾンビもありません。ここで、ARC に変更すると、テスト ボタンをクリックするたびにプログラムがクラッシュします。私は alertView 変数を保持していないので、それを推測しています。

このような便利なクラスを ARC でどのように行うことができますか?

.h ファイルの追加:

#import <Foundation/Foundation.h>

typedef void(^CallBackBlock)(int value);

@interface MyAlertView : NSObject<UIAlertViewDelegate>


@property (copy) CallBackBlock callBackBlock, internalCallBackBlock;

+(void)showWithTitle:(NSString *)title withCallBackBlock:(CallBackBlock )callBackBlock;
@end
4

1 に答える 1

0

その通りです。問題は、UIAlertView作成された showWithTitle:withCallBackBlock:internalCallBackBlock:internalCallBackBlockが保持されていないことです。

トリックは、 is を のインスタンス変数に格納することですMyAlertView。でMyAlertView.m、次を追加します。

@interface MyAlertView()
    @property(strong) UIAlertView *alertView;
@end

@implementation MyAlertView

@synthesize alertView;

...

そして、それを使用して、作成したものを次の場所に保存しUIAlertViewますshowWithTitle:withCallBackBlock:internalCallBackBlock:internalCallBackBlock

dispatch_async(dispatch_get_main_queue(), ^{
    self.alertView = [[UIAlertView alloc] initWithTitle:title message:title delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK" , nil];
    [self.alertView show];
});

PSこれは本当にペダンティックになりますが、MyAlertView実際にはビューではないので、名前を変更することをお勧めします.

于 2012-06-05T23:11:46.647 に答える