1

コーディング中に、IBOutletsの保持カウントに関する同じ質問が出てきました。NIBからオブジェクトをアーカイブ解除した後、カウントを保持しますか?IBOutletに@propertyを使用するのはいつですか?設定中に保持または割り当てますか?MacとiPhoneの違いは?

そこで、AppleのドキュメントからThe Nib ObjectLifeCycleを読みました。MacとiPhoneのいくつかのテストアプリは私にいくつかの奇妙な結果を与えました。それでも、コーディング中に満足するためにこの問題を処理する方法をいくつか書き留めましたが、コミュニティに確認して、あなたの意見や経験に耳を傾けたいと思いました。

  1. トップレベルオブジェクトのIBOutletを常に作成します。必要に応じて非トップレベルオブジェクトの場合(アクセスが必要)。
  2. IBOutletsには常に次のプロパティを提供します(必要に応じて解放します)。
    • Macのトップレベルオブジェクト:
      • @property(nonatomic、assign)IBOutlet SomeObject * someObject;
      • @synthesize someObject;
      • [self.someObjectリリース];
    • Macのトップレベル以外のオブジェクト(リリースなし):
      • @property(nonatomic、assign)IBOutlet NSWindow * window;
      • @synthesize someObject;
    • iPhoneのトップレベルオブジェクト(保持する必要があります):
      • @property(非アトミック、保持)IBOutlet SomeObject * someObject;
      • @synthesize someObject;
      • [self.someObjectリリース];
    • iPhoneのトップレベル以外のオブジェクト(保持する必要があります):
      • @property(非アトミック、保持)IBOutlet UIWindow * window;
      • @synthesizeウィンドウ;
      • [self.windowリリース];

サイドノート:

  • MacおよびiPhoneでは、可能な場合はセッターを使用してコンセントに接続します。
  • トップレベルオブジェクト:「所有オブジェクトがありません[...]」
  • 非最上位オブジェクト:「ビュー階層内にネストされたビューなど、親オブジェクトまたは所有オブジェクトを持つオブジェクト」。

したがって、質問は次のようになります。これは正しくて良い習慣ですか?

承認または修正していただければ幸いです。

4

6 に答える 6

10

常にnibsのファイルの所有者をNSWindowControllerまたはNSViewController(Mac OS Xの場合)またはUIViewController(iPhoneの場合)のサブクラスにし、そのすべてのアウトレットに使用して、コントローラーのサブクラスメソッド@property (retain) IBOutletで適切なリリースを実行します。-dealloc

このパターンは、Mac OSXとiPhoneOSの両方で正常に機能します。これは、Mac OS XのNSWindowControllerとNSViewControllerがトップレベルオブジェクトの暗黙の所有権を取得し(そして独自のメソッドでそれを放棄し-dealloc、iPhoneOSは何も取得しないためです。ペン先の読み込み中の最上位オブジェクトの暗黙的な所有権。

于 2010-01-21T04:10:04.177 に答える
1

トップレベルオブジェクト:「所有オブジェクトがありません[...]」

ニックス。トップレベルオブジェクトは、ファイル内のすべてのトップレベルオブジェクトを所有しているため、ファイルの所有者であるファイルの所有者によって所有されます。

Windowsには便利な方法でリリースするオプションがありますが、自分が所有する他のオブジェクトと同じように、オフにして自分でその存続期間を管理するか、ウィンドウを使用すると、デザインがよりクリーンになります(少し手間がかかりますが)。コントローラ。

これが引用しているドキュメントと矛盾すると思われる場合は、段落全体を見ていきましょう。

nibファイル内のオブジェクトは、最初は保持カウント1で作成されます。ただし、オブジェクト階層を再構築すると、AppKitは、ビュー階層内にネストされたビューなど、親オブジェクトまたは所有オブジェクトを持つすべてのオブジェクトを自動解放します。

したがって、それ自体の所有権を殺します。ニブローダーはオブジェクトを所有することを望んでいません。

nib-loadingコードが実行されるまでに、nibファイルの最上位オブジェクトのみが正の保持カウントを持ち、所有オブジェクトはありません。あなたのコードは、これらのトップレベルのオブジェクトを解放する責任があります。

言い換えれば、それはあなたに所有権を引き渡すことです。

その奇妙なアーティファクトは、オブジェクトのプロパティにセマンティクスが保持されている場合、実際にオブジェクトをリークすることです。ドキュメントには、それを保持する必要があると記載されています。

Mac OS XとUIKitの両方で、nibファイルのトップレベルオブジェクトを管理するための推奨される方法は、ファイルの所有者オブジェクトにそれらのアウトレットを作成し、必要に応じてそれらのオブジェクトを保持および解放するセッターメソッドを定義することです。

ただし、これを行うと、オブジェクトの所有権を解放した後でも、オブジェクトは存続します。

私はこれについてバグを報告するつもりだと思います。(編集:完了。x-radar:// problem / 7559755)少なくとも、nibローダーは私のテストアプリ(10.5.8および10.6.1)で行う2つの保持を渡すべきではありません。

于 2010-01-20T06:05:00.903 に答える
1

上記のアップルのドキュメントから:

Mac OS XとUIKitの両方で、nibファイルのトップレベルオブジェクトを管理するための推奨される方法は、ファイルの所有者オブジェクトにそれらのアウトレットを作成し、必要に応じてそれらのオブジェクトを保持および解放するセッターメソッドを定義することです。より適切なメソッドは、アプリケーションがガベージコレクションを使用する状況でも、メモリ管理コードを含めるための適切な場所を提供します。セッターメソッドを実装する簡単な方法の1つは、宣言されたプロパティを(@property構文を使用して)作成し、コンパイラーに作成させることです。プロパティを定義する方法の詳細については、Objective-Cプログラミング言語を参照してください。

それ以外の場合は、@ property(nonatomic、retain)IBOutlet*outletName;を使用します。

于 2010-06-29T23:36:41.000 に答える
0

iPhoneNIBの開発について意見を書くことができます。

  • IBを使用する場合は、できるだけ多くのIBOutletを使用するか(NIBを構築するときにビュー階層がわからない場合があります。動的である可能性があります)、まったく使用しないでください。そうしないと、混乱が生じます。
  • ビューコントローラの外部からビューにアクセスする場合にのみプロパティを使用します(パブリックにする必要がある場合)
  • AFAIKIBOutletsのメモリを管理する必要はありません

それが役に立てば幸い...

于 2010-01-20T00:29:33.460 に答える
0

標準のメモリ管理ガイドラインに従う必要があります。アウトレットがretainedプロパティに接続されている場合は、メッセージでそれを解放する必要があり-deallocます。

そして、はい、他のオブジェクトによって保持されていないトップレベルのオブジェクトは、通常、自分で保持する必要があります。

于 2010-01-20T00:33:24.263 に答える
0

1)一般に、とにかくそれを指すIBOutletのないトップレベルのオブジェクトがあるのはなぜですか?その要件は、これまで非常に制限されているようには見えませんでした。

2)iPhoneに適した設定ができたと思います。iPhoneでもassignプロパティを使用できます。これは、期待どおりの動作をします...しかし、一般的に、多くの使用の後、retainプロパティを使用することを好むので、オブジェクトが解放されたと見なすときに100%明確になります(特に実装するviewDidUnloadメソッドを使用します)。

また、補足として、[self.propertyrelease]を呼び出すのは適切な形式ではありません。これにより、参照はそのまま残りますが、他の何かがオブジェクトを解放した場合は、無効になる可能性があります... self.property = nilと言うか、(より適切に)deallocステートメントでプロパティを使用せずに基礎となるクラス変数を直接nilに設定します(デアロックで起こりうる副作用)。

別の投稿者への返信で述べたように、プライベートクラスローカルカテゴリ拡張で宣言されたIBOutletプロパティを使用して、パブリックプロパティではないようにすることで、物事をクリーンに保つことができます。それは次のようになります:

// in .m file
@interface MyClass ()
@property (nonatomic, retain) IBOutlet UIView *myPrivateView;
@end

@implementation MyClass
@synthesize myPrivateView;
.....
于 2010-01-20T06:55:40.890 に答える