2017-02-20 17 views
0

は、私は次のビューコントローラにカスタムオブジェクトを渡すしようとしていたと私はまだプロパティ属性を持つ非常に混乱しています。このエラークラスオブジェクトは、保持され、コピーされないプロパティ属性です。 、

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 

    if ([segue.identifier isEqualToString:@"attemptDetails"]) 
    { 
     ResultsVC *vc = segue.destinationViewController; 
     vc.selectedEntry = selectedEntry; 
    } 
} 

@property (nonatomic, retain) ClassName *selectedEntry; //Why is it retain and not copy?

が発生しましたし、なぜ特定の種類は、特定の属性を使用しますNSStringのように(nonatomic, copy)を使用し、CLLocationCoordinate2Dには(nonatomic, readonly)を使用します。

誰かがそれぞれのプロパティ属性がどのように機能するかを説明したりリンクしたりできますか?本当にありがとう!

+2

これを確認してください:http:// stackoverflow。com/a/7855536/4831524 –

+1

このリンクを確認する、http://stackoverflow.com/questions/2255861/property-and-retain-assign-copy-nonatomic-in-objective-c http://stackoverflow.com/a/15541801/4294543 –

+0

@iamhxさんはストーリーボードに識別子を指定しましたか? –

答えて

0

Objective Cでは、各クラスに実際にその背後に構造があることがわかります。プロパティは、構造体、ゲッター、セッターに値を作成するショートカットです。例えば:

@interface MyClass 

@property id myValue; 

@end 

が作成されます:

@interface MyClass { 
    id _myValue; 
} 

@property id myValue; 

@end 

@implementation 

- (id)myValue { 
    return _myValue; 
} 
- (void)setMyValue:(id)myValue { 
    _myValue = myValue; 
} 

@end 

を今、このようなretaincopyとしてこれらのフラグは、セッターとゲッターに追加のロジックを追加します。値がcopyメソッドを実装しなければならないことを意味し

- (void)setMyValue:(id)myValue { 
    _myValue = [myValue copy]; 
} 

copyを使用すると、実際にはセッターを作成します。あなたのオブジェクトはクラッシュしないので。

コピーを使用するのは安全のためです。これは文字列としてはあまり重要ではありませんが、配列のようなものにとっては重要です。したがって、たとえば、変更不可能な配列を期待するプロパティ@property NSArray *myArray;を作成しますが、問題は可変配列を設定することも可能です:myClassInstance.myArray = [[NSMutableArray alloc] init];。現在、2つのモジュールが同じ可変配列にアクセスできます。したがって、最初のオブジェクトが配列の変更を開始し、もう一方の配列が配列が常に同じであることが予想される場合、いくつかの問題が見つかる可能性があります。たとえば、MyClassインスタンスでは、テーブルビューのデータソースとしてこのインスタンスを使用でき、ある時点では配列は変更されていますが、セルは追加/削除されず、テーブルビューによってクラッシュが発生します。

これらのすべてをデフォルトにして、本当に必要なときにのみ変更することができます。とにかく上記のようなケースはほとんどありません。プロパティは、説明を属性の記述がたくさんある

+0

面白い... .hファイルの '@interface {}'では、 'NSString * myString;'のようなものを宣言して.mファイルで ' self.myString; '私の質問は、.mファイルには '@interface {}'もあります。これらのインターフェイスはどちらも同じですか? – iamhx

+1

これらは同じですが、ソースファイル(.m)のファイルは通常プライベート(またはファイルプライベート)として扱われます。ほとんどの場合、そこにあるものすべてを宣言しようとしますが、他のクラスのファイルに公開する必要がある値です。そして、公開されているものは常にプロパティでなければならないので、そのクラス外のロジックを変更することなく(セッターをオーバーライドするなど)ロジックを制御することができます。要するに、パフォーマンスを最適化するようなことを100%確実にしていない限り、ソースファイルにこれらをすべて入れてください。 –

+0

また、インターフェイスに読み取り専用フラグが設定されている場合は、インターフェイスとソースファイルの両方に同じプロパティを設定できます。つまり、プロパティを読み取り専用として公開しますが、ソースファイル内で内部的にプロパティを割り当てることができます。 –

1

参照リンク、

Objective-C ARC: strong vs retain and weak vs assign

https://stackoverflow.com/a/4511004/4294543

@property and retain, assign, copy, nonatomic in Objective-C

ショートシンプル&私の理解が似ている、

保持:作成されたオブジェクトを処理しているだけで、参照カウントが増えます。

  • ここでは、すでにクラスオブジェクトをモデル化しているので、2番目のvcプロパティにコピーする必要はありません。2番目のvcプロパティに保持するだけです。

コピー:あなたはプロパティに割り当てられた値があまりにも他の目的に使用&をコピーすることができます(オブジェクトが変更可能であるとき&はそれに仕上げた後、解放する必要があるオブジェクト&必要性の簡易コピーを作成します)。

ノンアトミック:スレッドアクセスは高速ですが、同時にアクセスすることはできません&あなたのプロパティを変更します。

読み取り専用:プロパティに新しい値を直接割り当てることはできません。

でも、私はメモリ管理のための良い記事のカップルを読んだことが、私のプロジェクトに

#import "ViewController.h" 
#import "TestViewController.h" 
#import "CustomClass.h" 
@interface ViewController(){ 

    CustomClass *classT; 
} 

@end 
@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    classT = [[CustomClass alloc]init]; 
    classT.test = YES; 

} 
- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 
- (IBAction)btn:(id)sender { 
    TestViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"TestViewController"]; 
    vc.className = classT; 
    [self presentViewController:vc animated:YES completion:nil]; 
} 
@end 




#import <UIKit/UIKit.h> 
#import "CustomClass.h" 

@interface TestViewController : UIViewController 


@property (nonatomic,retain) CustomClass *className; // Work as i said 

//@property (nonatomic,copy) CustomClass *className; // Makes a copy of an object, and returns it with retain count of 1. If you copy an object, you own the copy. This applies to any method that contains the word copy where “copy” refers to the object being returned thats why here you will get crash 


@end 
1

をあなたのケースを実行しました。 rypress

保持属性:retain属性は、強力なManual Retain Releaseバージョンであり、割り当てられた値の所有権を主張するのとまったく同じ効果を持ちます。 Automatic Reference Counted環境では使用しないでください。

コピー属性:コピー属性はstrongの代わりです。既存のオブジェクトの所有権を取得する代わりに、プロパティに割り当てられたもののコピーを作成し、その所有権を取得します。 NSCopyingプロトコルに準拠しているオブジェクトだけがこの属性を使用できます。

でも、私はstackoverflowの良いリンクも行っていました。 Joshua Nozzi's answerは、保持対コピーについてよく説明しました。

はコピー対保持 - 宣言されたプロパティを使用して、デフォルトで保持(あなたは単にそれを完全に省略することができます)と別のオブジェクトがプロパティに割り当てられているか、それがnilに設定されていますかどうか、自動的にオブジェクトの参照カウントを管理します。コピーを使用すると、新しく割り当てられたオブジェクトを自動的に送信します(渡されたオブジェクトのコピーを作成し、そのコピーをプロパティに割り当てる代わりに、割り当てられたオブジェクトが変更される可能性がある場合もありますいくつかの他のオブジェクトのプロパティとして設定(その変更を意味するだろう/突然変異は、同様の特性に適用される)

がまた良い例hereを見つけ

コード:。。

NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"First",@"Second", nil]; 
    NSMutableArray *copiedArray = [array mutableCopy]; 
    NSMutableArray *retainedArray = [array retain]; 

    [retainedArray addObject:@"Retained Third"]; 
    [copiedArray addObject:@"Copied Third"]; 

    NSLog(@"array = %@",array); 
    NSLog(@"Retained Array = %@",retainedArray); 
    NSLog(@"Copied Array = %@",copiedArray); 

出力:

array = (
    First, 
    Second, 
    "Retained Third" 
) 
2013-12-19 17:15:49.380 RetainVsCopy[2876:c07] Retained Array = (
    First, 
    Second, 
    "Retained Third" 
) 
2013-12-19 17:15:49.381 RetainVsCopy[2876:c07] Copied Array = (
    First, 
    Second, 
    "Copied Third" 
) 

配列と保持された配列の両方が同じ内容を持っています。これは、両方とも同じメモリ/インスタンス/オブジェクトを指しているためです。 Copied Arrayの内容が異なる場合。これは、コピーが別のインスタンスを作成したためです。

関連する問題