1

強力な ivar を必要としない UIAlertView に似たクラスを作成したいと考えています。

たとえば、UIAlertView を使用すると、UIViewController のメソッドの 1 つで次のことができます。

UIAlertView *alertView     = [[UIActionSheet alloc] initWithTitle:nil
                                                          message:@"Foo"
                                                         delegate:nil
                                                cancelButtonTitle:@"Cancel"
                                                otherButtonTitles:nil];
[alertView show];

... そして、actionSheet は、表示されなくなるまで解放されません。

私が同じことをしようとした場合:

MYAlertView *myAlertView = [[MYAlertView alloc] initWithMessage:@"Foo"];
[myAlertView show];

...myAlertViewインスタンスは、現在のメソッドの最後 (たとえば、行の直後[myAlertView show]) で自動的に割り当て解除されます。

myView を UIViewController のプロパティとして宣言することなく、これを防ぐ適切な方法は何strongですか? (つまり、myView をインスタンス変数ではなくローカル変数にしたい。また、ライフサイクルを制御する UIViewController ではなく、MYAlertView インスタンスが独自のライフサイクルを担当するようにしたい。)

更新: MYAlertView は NSObject から継承されるため、Views 階層に追加することはできません。

4

4 に答える 4

5

UIAlertViewを作成しUIWindow、それを保持します。次に、アラート ビューがウィンドウのサブビューとして追加されるため、ウィンドウはアラート ビューを保持します。したがって、それとそのウィンドウの両方を維持する保持サイクルが作成されます。 UIActionSheet同じように動作します。

オブジェクトを保持する必要があり、他に何も保持しない場合は、それ自体を保持しても問題ありません。不要になったときにそれ自体を解放する明確な方法があることを確認する必要があります。たとえば、ウィンドウを管理している場合は、ウィンドウを画面から外すときに解放する必要があります。

于 2013-07-09T23:57:05.677 に答える
2

別のビューのサブビューとして追加すると、保持されます。ユーザーがそれを選択してアクションまたは却下すると、最後のアクションとして self removeFromSuperview を呼び出す必要があります。

于 2013-07-09T23:03:53.610 に答える
2

ちょっとしたトリックで独自の AlertView を作成しました。

オブジェクトを自分で保持し、アクションでリリースするだけです。これにより、カスタムアラートバイをネイティブのものとして呼び出すことができます。

#import "BubbleAlertView.h"
#import <QuartzCore/QuartzCore.h>

@interface BubbleAlertView ()
...
@property (nonatomic, strong) BubbleAlertView *alertView;
...

@end

@implementation BubbleAlertView

...

- (id)initWithTitle:(NSString*)title message:(NSString*)message delegate:(id)delegate cancelButtonTitle:(NSString*)cancelButtonTitle okButtonTitle:(NSString*) okButtonTitle
{
self = [super init];
if (self)
{
    // Custom initialization
    self.alertView = self; // retain myself

    //More init stuff 
}
return self;
}
...

//SHOW METHOD

- (void)show
{
// We need to add it to the window, which we can get from the delegate
id appDelegate = [[UIApplication sharedApplication] delegate];
UIWindow *window = [appDelegate window];
[window addSubview:self.view];

// Make sure the alert covers the whole window
self.view.frame = window.frame;
self.view.center = window.center;

}

- (IBAction)btPressed:(id)sender
{
//Actions done

[UIView animateWithDuration:0.4f animations:^{
    self.vContent.alpha = 0.f;
} completion:^(BOOL finished) {
    [self.view removeFromSuperview];
    self.alertView = nil; // deallocate myself
}];

}
于 2013-07-10T14:28:20.053 に答える
1

リリースされるまで、何らかの方法で保持する必要があります。

のサブクラスとして実装できない理由がよくわかりませんUIView。次に、ビュー階層を強い参照のキーパーとして使用できます (保持 +1)。しかし、そうしないのには十分な理由があります。

あなたがそのようなものを持っていないなら、私はNSMutableArrayas class varialbe (つまり statc) を使用します。@interfaceブロックで宣言し、nil で初期化するだけです。

@interface

static NSMutableArray _allMyAlerts = nil;

アクセサーを提供します。

-(NSMutableArray *) allMyAlerts {

  if (_allMyAlerts == nil) {
     _allMyAlerts = [[NSMutableArray alloc] init];
  }
  return _allMyAlerts
}

init メソッド内で次の操作を行います。

- (id) init {

  self = [super init];
  if (self) {
    [[self allMyAlerts] addObject:self];
  }

}

アラートが閉じられたときに何らかのメソッドを呼び出します。

- (void) dismissAlert {

  // Do your stuff here an then remove it from the array. 

  [[self allMyAlerts] removeObject:self];
}

マルチスレッド保存にするために何かを追加したい場合がありますが、そうではありません。概念を説明する例を挙げたいだけです。

allMyAlert も可能NSMutableSetです。私が見る限り、配列は必要ありません。オブジェクトを配列またはセットに追加すると、保持カウントが 1 追加され、削除すると 1 減少します。

于 2013-07-09T23:34:29.650 に答える