0

初心者の質問があります。(単一のメソッド/関数ではなく) コードのすべての部分で UIView にアクセスしたいと考えています。

したがって、 @interface セクションで宣言しました

UIView *calendarView;

そして@property (nonatomic, retain) UIView *calendarView。@implementation には@synthesise calendarView.

ここで、このビューのフレームを定義し、次のようにコーディングしたいと思います。

    CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
calendarView = [[UIView alloc] initWithFrame:calendarFrame];

しかし、calendarView は既に保持され合成されているため、ここで深刻な問題を起こしているのではないかと考えています。メモリの問題が発生しているため、確かに UIView alloc は不要であるか、アプリをクラッシュさせる可能性さえありますよね?

したがって、前の 2 行の代わりにこれをコーディングする必要がありますが、calendarView がまったく表示されないという効果しかありませんでした。

[calendarView setFrame:CGRectMake(170, 8, 200, 50)];

私の質問は、ビューを使用する前に本当にビューを割り当てる必要があるかどうかです。それともまだ別の解決策がありますか?

4

5 に答える 5

2

オブジェクトをメモリに保持した後(つまり、割り当てた後)にのみオブジェクトを保持できます。したがって、以下のコードは正しく、必要です。

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
calendarView = [[UIView alloc] initWithFrame:calendarFrame];//you have alloc'ed once

次に、このビューをparentViewに追加します。たとえば、私はUIViewController実装の内部にいます。

[self.view addSubView:calendarView];  //now only your retain takes place. //So now calenderView has to release twice..Once by you (since you alloced it) and once by viewcontroller (since it has retained it)...
[calendarView release];//we are releasing once but the object will not be removed from memory since it is retained by viewController..Our part in memory management is over..Now when this viewController get dealloced it releases 

このUIViewControllerの実装全体でこのcalendarViewを使用できます。

-(void)dealloc{
 [super dealloc];//should be last in dealloc..Now the entire controller will be dealloced along with the calenderView which is retained by viewController and the memory will be freed for future uses..
}

これらはいくつかの便利なチュートリアルです。アップルのドキュメントよりも理解しやすいですが、アップルのドキュメントも読んでください。

http://ferasferas.wordpress.com/2010/12/05/introduction-to-memory-management-on-iphone/

http://iosdevelopertips.com/objective-c/memory-management.html

http://mauvilasoftware.com/iphone_software_development/2008/01/iphone-memory-management-a-bri.html

https://humblecoder.blogspot.com/2009/08/iphone-tutorial-memory-management.html

于 2011-04-27T12:38:08.540 に答える
1

はい、

を使用する前に、他のソースから割り当てるか取得する必要があります(保持しているため、deallocで解放します)UIView

以下を使用してください

   CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];

メモリ管理については、アップルのドキュメントをお読みください。

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

于 2011-04-27T12:37:17.470 に答える
1

したがって、 @interface セクションで宣言しました

そうです、これは type+name で ivar にアクセスするためのスペースとラベルを予約するだけです

次に @property (非アトミック、保持) UIView *calendarView。

右、アクセサー (セッター + ゲッター) を宣言し、合成された場合の操作

@implementation には @synthesise calendarView があります。

これは、プロパティ宣言によって宣言されたアクセサーを定義 (実装) します。

ここで、このビューのフレームを定義し、次のようにコーディングしたいと思います。

...しかし、calendarView は既に保持され合成されているため、ここで深刻な問題を起こしているのではないかと考えています。メモリの問題が発生しているため、確かに UIView alloc は不要であるか、アプリをクラッシュさせる可能性さえありますよね?

1 つは、メモリ管理がオフになっていることです。

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
UIView * view = [[UIView alloc] initWithFrame:calendarFrame];
self.calendarView = view; // use the setter, unless in init... or dealloc
[view release], view = 0;

2: 通常、UIView の作成にはあまり使用されません。通常、そのサブクラスを作成します。

3 (あなたの質問にたどり着くため): それは何も悪いことではありません。変数は、nil設定されるまでそのままです。フィールドは、宣言された型に対してデフォルトで初期化されていません-まあ、そうですが、型は実際にはポインターであるため、結果は nil に初期化されます。ビューを作成するか、別の場所から渡すことができます。ビューはその時点まで nil/NULL/0 になります。

したがって、前の 2 行の代わりにこれをコーディングする必要がありますが、calendarView がまったく表示されないという効果しかありませんでした。

[calendarView setFrame:CGRectMake(170, 8, 200, 50)]; 私の質問は、ビューを使用する前に本当にビューを割り当てる必要があるかどうかです。それともまだ別の解決策がありますか?

ポイント 2 に戻ります。ほとんどの場合、サブクラスを作成する必要があります。UIView/NSView はデフォルトでは描画しませんが、ビュー コンテナーとして使用できます。したがって、既存のサブクラスから始めて、システム提供のビューに慣れることができます。

それを理解したら、独自のサブクラスを実装してオーバーライドしてみてくださいdrawRect:

多くの初心者は Interface Builder (現在は Xc4 に統合されています) -- WYSIWYG ビュー エディターの使用を好みます。

于 2011-04-27T12:43:42.997 に答える
1

プロパティを合成しても、実際にはオブジェクトがインスタンス化されません。alloc メソッドと init メソッドは引き続き必要です。

上記のコードで、プロパティを使用する場合はself.calendarView、 だけではなくを使用する必要がありますcalendarView。(後者を行うことは、プロパティをバイパスしてインスタンス変数を直接使用することです。これは通常、deallocメソッド内での例外の可能性を除いて、必要なものではありません。)

行う必要がある最後の変更: プロパティが保持とマークされている場合、オブジェクトはそれ自体の周りに保持されます。したがって、入れているオブジェクトを自動解放する必要があります。これを試して:

self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
于 2011-04-27T12:33:31.817 に答える
1

最初の例では、メモリリークの可能性を除いて、実際には何も間違っていません。それがあなたのプロパティを定義した方法であったため、calendarViewがすでに保持されているという間違った考えがありますが、これは正しくありません。プロパティを保持として定義すると、 を呼び出したときにself.calendarView = someotherviewsomeotherview保持され、calendarView の古い値が解放され、calendarView が に設定されsomeotherviewます。self なしで calendarView を使用しても、プロパティのようなメモリ管理ルールは提供されないため、最初の例は問題ありません。コードを次のように表示したい場合があります。

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
于 2011-04-27T12:34:34.140 に答える