2012-03-19 7 views
2

私はインスタンス変数_myStringにmyStringを合成する目的が何であるかを調べようとしています。iPhoneインスタンスの変数の問題

これを行う目的は何ですか?私はこれをやっている人が多いことに気づく傾向があります。

また、インスタンス変数を解放し、インスタンス変数をnilに設定する必要があります。正しいです。

ViewController.h

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController 
{ 
    NSString *_myString; 
} 

@property (nonatomic, retain) NSString *myString; 

@end 

ViewController.m

#import "ViewController.h" 

@implementation ViewController 

@synthesize myString = _myString; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.myString = [[NSString alloc] initWithFormat:@"Hello"]; 

    _myString = [[NSString alloc] initWithFormat:@"Goodbye"]; 

    NSLog(@"%@\t%@", self.myString, _myString); 
} 

- (void)viewDidUnload 
{ 
    _myString = nil; 
    [super viewDidUnload]; 
} 

- (void)dealloc 
{ 
    [_myString release]; 
    [super dealloc]; 
} 

@end 
(技術[自己のmyString])は、実際にアクセスしように書かれ、このオブジェクト内の関数を介して_myString IVAR設定さ
+0

ウルの評判については、私がなぜ合成を使用するのかという知識が必要です.....私の意見では、合成は主にオブジェクトをグローバルに使用したいときに使用されます(別のアドリートもあります)。 ).. ..私が知っているように:) – Krunal

+0

私はそれがインスタンス変数と等しいに設定することによってゲッターとセッターを作成する合成を知っていますか? – Vikings

+0

ひとつ: 'viewDidUnload'に' _myString'をnil-outしてはいけません。このメソッドは 'viewControllers''view'がアンロードされ、これはプロパティ' myString'(またはiVar '_myString')とは関係ありません。 'viewDidUnload'では、例えば、いくつかの' .xib'に接続されている 'IBOutlet'をnil-outする必要があります。 –

答えて

3

オブジェクトcのオブジェクト型プロパティを@synthesizeすると、コンパイラはそのインスタンス変数に対して2つの隠しメソッドを生成します。したがって、myObject.myStringを参照すると、_myStringのポインタが返されるだけでなく、生成された- (NSString*) myStringメソッドが呼び出されます。同様にプロパティに何かを割り当てた場合:myObject.myString = @"foo";[myObject setMyString:@"foo"];にコンパイルされます。

- (NSString*) myStringおよび- (void) setMyString:(NSString*) theStringにあるものは、プロパティを宣言するときに指定するキーワードによって異なります。

- (void) setMyString:(NSString*) theString 
{ 
    _myString = theString; 
} 

- (NSString*) myString 
{ 
    return _myString; 
} 

これは、パブリック変数を_myString宣言からも過言ではない違いが、それはこの変数は、外部から直接アクセスすることができることを言うために、より明示的な方法である:最も一般的なのは、単純なあなたが与えるポインタを割り当てることassignです。ターンで

retainは(getterメソッドが同じになります)と同様のセッターメソッドを生成します。

- (void) setMyString:(NSString*) theString 
{ 
    [theString retain]; 
    [_myString release]; 
    _myString = theString; 
} 

あなたは、これはあなたがプロパティに渡されたオブジェクトのメモリ管理の世話をすることがわかります。言い換えれば、所有物を所有するまでオブジェクトが解放されないことを確実にすることができるため、所有権を取ったときに手作業でretainする必要はありません。これにより、漏れなくメモリを管理するコードを書く方がずっと便利です。 deallocでは、格納された最後のオブジェクトを解放するために、まだプロパティにnilを適用する必要があることに注意してください。

プロパティの別のカテゴリは、インスタンス変数からのデータではなく、データベースなどの他のデータソースからのものです。例えば、コアデータの管理対象オブジェクトの自動生成プロパティはそのように機能します。

最後に、独自のゲッタとセッタを定義することもできます。例えば良いアイデアは、そのアクセスを容易にするであろういくつかの頻繁に使用されるNSUserDefaults設定の周りのプロパティラッパーを書くために:

@interface Bar 

@property (nonatomic, assign) NSString* foo; 

@end 

@implementation Bar 

- (void) setFoo:(NSString *)theFoo 
{ 
    [[NSUserDefaults standardUserDefaults] setObject:theFoo 
               forKey:@"settings.foo"]; 
} 

- (NSString*) foo 
{ 
    return [[NSUserDefaults standardUserDefaults] 
     stringForKey:@"settings.foo"]; 
} 

@end 

myBar.foo = @"foobar"; // automatically persisted between application runs 

を読むこれらも:Advanced memory managementDeclared properties in objective C

+0

私のプロジェクト全体を通して、私は_myStringまたはself .myString?私はself.myStringを推測しています。 – Vikings

+1

はい、initおよびdeallocを除きます。ここでその理由を説明します:https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447-SW4 – MrTJ

+0

ありがとう、それをクリアした。 – Vikings

1

self.myStringこれは

-(NSString *)myString { 
    // code that is automatically generated by the @synthesize statement OR 
    // code that you write which over-rides the generated accessor. 
    // both of which generally return the value stored in _myString 
} 

-(void)setMyString:(NSString *)newString{ 
    // code that generally changes the value of _myString 
} 

を使用すると、これらの関数を直接バイパスすることができます。 ivarに直接アクセスします。

0

人は、他のコードを書くときに2つの間違いがないように、接頭辞付きの変数にアンダースコアを付けるためにプロパティを合成する傾向があります。例:

// ... do sth 
myString = @"Foo"; 
// ... do sth else ... 
self.myString = @"Bar"; 

最初の命令は変数に直接アクセスし、2番目の命令は合成されたセッターを使用します。あなたが特定の変数、プロパティが自動的に作成されたものと同じ名前を持つ、変数を指すずに合成するとき:

@synghesize myString; // this creates myString variable for you 

の代わりにこれをやって、人々は誤ってそれを直接アクセスしないようするために、アンダースコアの接頭辞変数を作成します。彼らがそれをするとき、最初の指示myString = @"Foo"はもはやコンパイルされないので、誤ってゲッターやセッターをバイパスしたときのような厄介なバグを非常に簡単に防ぐことができます。

2番目の質問については、できるだけARCを使用してください。そうでない場合は、最初に変数を解放してからポインタをリセットする必要があります。あなたが提示したコードでは、viewDidUnloadはdeallocより前に呼び出されるので、releaseが呼び出される前に_myStringがnilを指すため、メモリリークが発生します。