Objective-Cの弱くて強いプロパティセッター属性


94

Objective-Cのプロパティセッターの弱い属性と強い属性の違いは何ですか?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

影響とメリットは何ですか?

ウィークはiOS 4では使用できず、割り当てを使用する必要があると聞きました。

弱いと割り当てに似ていますか?


回答:


102

特定のファイルに対してARCをオンまたはオフにします。オンの場合、retain release autoreleaseetc ...を使用できません。代わりにstrong weak、プロパティまたは__strong __weak 変数に使用します(デフォルトは__strong)。強力は保持と同等ですが、ARCがリリースを管理します。

weakを使用したいのは、保持サイクルを回避したい場合のみです(たとえば、親は子を保持し、子は親を保持するため、どちらも解放されません)。

「フリーブリッジング」部分(からNSへのキャストCF)は少しトリッキーです。それでも、手動でCFオブジェクトを管理する必要がCFRelease()ありCFRetain()ます。それらをNSオブジェクトに戻すときは、保持カウントについてコンパイラーに通知する必要があります。これにより、コンパイラーは何を行ったかを認識します。

そのすべてがここにあります


119

変数のプロパティについて知っている情報は次のとおりです

  1. アトミック//デフォルト
  2. 非原子
  3. strong = retain //デフォルト
  4. 弱い
  5. 保持する
  6. //デフォルトを割り当てる
  7. unsafe_unretained
  8. 写す
  9. 読み取り専用
  10. readwrite //デフォルト

以下は、上記のすべての属性を見つけることができる詳細な記事のリンクです。ここで最高の答えをくれたすべての人々に感謝します!!

iOSの可変プロパティ属性または修飾子

01. 強い(iOS4 =保持) -「もう指さなくなるまでこれをヒープに」と表示されます-言い換えると、「私は所有者です。保持するのと同じように、目標を定める前に割り当てを解除することはできません。 "-オブジェクトを保持する必要がある場合のみ、ストロングを使用します。-デフォルトでは、すべてのインスタンス変数とローカル変数は強力なポインターです。-通常、UIViewControllers(UIアイテムの親)にはstrongを使用します。strongはARCで使用され、オブジェクトの保持カウントを気にする必要がないため、基本的には役立ちます。ARCは、作業が完了すると自動的に解放します。strongキーワードを使用すると、オブジェクトを所有していることになります。

例:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. 弱い(iOS4 = unsafe_unretained) -「誰か他の人が強く指摘する限り、これを保持する」-割り当てと同じこと、保持または解放しない-「弱い」参照は、保持しない参照です。-通常、IBOutlets(UIViewControllerの子)にはウィークを使用します。これは、親オブジェクトが存在する限り子オブジェクトが存在する必要があるだけなので機能します。-弱参照は、参照されたオブジェクトをガベージコレクタによるコレクションから保護しない参照です。-弱いは本質的に割り当てられていない、保持されていないプロパティです。オブジェクトが割り当て解除されるときを除いて、ウィークポインターは自動的にnilに設定されます

例:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

説明BJホーマーに感謝

オブジェクトが犬であり、犬が逃げる(割り当て解除される)ことを望んでいると想像してください。強いポインタは、犬の首輪のようなものです。犬に紐を付けている限り、犬は逃げません。5人が1つの犬にリーシュを取り付けた場合(1つのオブジェクトへの5つの強力なポインタ)、犬は5つすべてのリーシュが外れるまで逃げません。一方、弱いポ​​インタは、犬を指して「見て!犬!」と言う小さな子供たちのようなものです。犬がまだひもにつながっている限り、小さな子供たちは犬を見ることができ、彼らはそれを指さし続けます。しかし、すべての鎖が外れるとすぐに、いくつ小さな子供が指を指していても、犬は逃げます。最後の強いポインター(リーシュ)がオブジェクトを指さなくなるとすぐに、オブジェクトは割り当て解除され、すべての弱いポインターはゼロにリセットされます。弱く使うと?weakを使用したいのは、保持サイクルを回避したい場合のみです(たとえば、親は子を保持し、子は親を保持するため、どちらも解放されません)。


1
最初のリストでは、「デフォルト」の意味がよくわかりません。両方がstrong=retainありassign、デフォルトとしてラベル付けされていますが、両方にすることはできません。
Slipp D. Thompson 2013

27
鎖の比較で犬を楽しんだ。かなりよく説明しています。
Jarrett Barnett

1
iOSはガベージコレクションを使用しませんが、良い説明です。ARC!=ガベージコレクション(!)、これらは異なるテクノロジーです。

1
weakとunsafe_unretainedは異なります(最初は弱いゼロ参照を使用しますが、後者はスクワットします)
wcochran

1
私はiOSのみを学習していますが、weakとのstrong例を間違えているようです。親がstrongその子への参照を持っていること(あなたが示しmyButtonUIViewControllerクラスのプロパティとしてweak)と、子weakが親への参照を保持していること(つまりviewController、子クラスのプロパティのように)代わりにveに設定strong)。たとえば、Matt Neuburgの記事を読むとiOS 7 Programming Fundamentals、デリゲートをプロパティとして宣言しているクラスは、それを「弱く保つ」ことを示しています。
Bogdan Alexandru 14

2

最後の2つの質問に明確に答えるRobertが参照するドキュメントの部分を呼び出すには、次のようにします。

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

これはゼロ化弱参照と呼ばれます。__unsafe_unretainedを使用して、弱参照をゼロにしない弱参照を作成できますが、その名前が示すように、これは一般に推奨されません。

ドキュメントでも:

Weak references are not supported in Mac OS X v10.6 and iOS 4.

1
はい、これは正しい __unsafe_unretainedです。ARCバージョンですassign
ロバート

2

WEAKプロパティの明確な使用法は次のとおりです。

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;

1
プロパティにウィークを使用すると、「弱いレシーバーが予期せずnilに設定される可能性があります」という警告が表示されます。この警告を防ぐために、ローカルの強い参照を作成する必要がある他の投稿をいくつか見ました。そして、これが本当である場合、最後に強い参照を作成する必要がある場合、プロパティを弱くする意味は何ですか?
2015年

0

もっと詳しく説明する例を挙げましょう(上の答えはすでに素晴らしいです)、この例はもう少し役立つかもしれません

2つのクラスAとBがあるとします

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    {
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   }

上記のコードは両方ともストロングタイプであるため、保持サイクルを生成しますa --------> b ---------> a

それを回避するには、そのいずれかの週プロパティを使用して、毎週オブジェクトを参照し、参照カウントを増加させないようにする必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.