0

さて、Objectivecの初期化クラスのプロパティに問題があります。たくさんの情報を読みましたが、質問に対する答えが見つかりませんでした。だから私は例を挙げます。1)

//Ex_1.h
@interface Ex_1: UIView {
   IBOutlet UIButton *playBut;
}

@property(retain, nonatomic) IBOutlet UIButton *playBut;
-(void) method1;

@end

//Ex_1.m
@implementation Ex_1
@synthesize playBut;

-(id) initWithFrame:(CGRect)frame {
  self = [super initWithFrame : frame];
  if (self != nil)
      playBut = [UIButton buttonWithType:UIButtonTypeRoundedRect]; //retainCount of playBut = 1;
  return self;

}

-(void) method1 {
   [playBut setTitle:@"pause" forState:UIControlStateNormal];
}

@end

私は最初にEx_1のオブジェクトを初期化し、次にこのオブジェクトのmethod1([object method1])を呼び出すと、ランタイムエラーが発生します(エラーはplayButがdeallocであることを示していますが、playButの保持カウント= 1だと思います)。だから私はいくつかの質問があります:

  1. 出来ますか ?
  2. ガベージコレクターがplayButの割り当てを解除するのはなぜですか?(保持カウント= 1の場合)([playButrelease]を呼び出さないため)。
  3. クラスプロパティを初期化するにはどうすればよいですか?

私はC++とactionScriptに精通していますが、ガベージコレクターがクラスプロパティの割り当てを解除したことを人生で初めて見ました。ARC以外を使用しています。それは私にとって重要です。ご清聴ありがとうございました。

4

2 に答える 2

2

[UIButton buttonWithType:] returns an autoreleased object. It will be alive for the lifetime of the scope in which you call it, i.e. initWithFrame: but the autorelease pool can reclaim it after that. You should instead say, in your init selector:

playBut = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];

Then send this in your dealloc:

[playBut release];

Now, if you were to add the playBut as a child to another UIView, that view would retain the child and you wouldn't need to, as long as you only use it during the lifetime of the super view. This is a normal pattern. You could go further and assign a tag to playBut then use viewWithTag: to find your UIButton when you need it.

于 2013-02-16T17:41:20.100 に答える
1

You may be confused because your property declaration includes a retain. However you are assigning directly to your iVar here:

      playBut = [UIButton buttonWithType:UIButtonTypeRoundedRect]; //retainCount of playBut = 1;

so not taking advantage of the property setter, so it doesn't retain for you.

So either:

       self.playBut = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 

Or:

       playBut = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain]; 

Of the two, using self.playBut is far better - you should be using properties and their accessors all the time unless you have good reason not to. And no need to declare the iVar separately (or @synthesize these days). See my answer here: Should I declare variables in interface or using property in objective-c arc?

As regards your particular example using UIButtons, they usually get added directly into the UI, which does the retaining for you, so you wouldn't experience this. That's why IBOutlets are normally declared weak (ARC) or assign (nonARC).

于 2013-02-16T17:46:21.813 に答える