2012-02-26 13 views
5

ARCの仕組みを理解しようとしています。私が知る限り、ここで間違ったことをしているはずです。これは私が使用しているコードです:iOS ARC - 弱くて強い性質

インタフェース:

@interface ViewController : UIViewController{ 

} 

@property (strong, nonatomic) NSString * myString ; 
@property (weak, nonatomic) NSString * myPointer ; 

実装:

- (void)viewDidLoad{ 

    [super viewDidLoad]; 
    self.myString = @"Hello world!" ; // myString is strong 
    self.myPointer = self.myString ; // myPointer var is weak 

    [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];  
    [self performSelector:@selector(printValues) withObject:nil afterDelay:2];  
} 

- (void) makeNilMyValue{ 
    self.myString = nil ; 
} 

- (void) printValues{ 
    NSLog(@"myString: %@", self.myString) ; 
    NSLog(@"myPointer: %@", self.myPointer) ; 
} 

がこれを実行した後、私が手:

2012-02-26 11:40:41.652 test1[933:207] myString: (null) 

2012-02-26 11:40:41.653 test1[933:207] myPointer: Hello world! 

の場合私は間違っていない、myPointerのためです弱い、それはオブジェクトの内容を保持すべきではありません。だから、 "Hello World!"の代わりにnilが表示されるはずです。

私は間違っていますか?

カレブの答えの後、私は別の弱いポインタを作成しているが、以下のコードを参照してください。ポイントは、私はまだ私が持っていた同じ答えを得たことである

- (void)viewDidLoad{ 
    [super viewDidLoad]; 
    self.myString = @"Hello world!" ; // myString is strong 
    self.myPointer = self.myString ; // myPointer var is weak 
    self.myPointer2 = self.myString ; // myPointer2 var is weak 

    [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];  
    [self performSelector:@selector(printValues) withObject:nil afterDelay:2];  
} 

- (void) makeNilMyValue{ 
    self.myPointer2 = @"value changed!" ; 
    self.myString = nil ; 

} 

- (void) printValues{ 
    NSLog(@"myString: %@", self.myString) ; 
    NSLog(@"myPointer: %@", self.myPointer) ; 
} 

を:

2012-02-26 12:08:13.426 test1[1333:207] myString: (null) 
2012-02-26 12:08:13.427 test1[1333:207] myPointer: Hello world! 

答えて

8

Calebが指摘したように、この例では定数NSStringを使用するのは良い考えではありません。

ソースコード内の文字列オブジェクトを作成する最も簡単な方法は、Objective-Cの@を使用することです "..." 構築:

NSStringの* TEMP = @ "を/ tmp /スクラッチ"。このように文字列 を作成するときは、7ビットの ASCII文字以外のものを使用しないでください。このようなオブジェクトは、コンパイル時に作成され、プログラムの実行中には 存在します。コンパイラは、このようなオブジェクトをモジュールごとに一意にして、他のオブジェクトと同じように保持して解放することができますが、 という割り当てを解除することはありません。 =同じ

BOOL [「比較」isEqualToString @:のmyString]あなたはどの 他の文字列がそうであるようにあなたは また、文字列定数に直接メッセージを送ることができます。

documentationは、定数文字列が決して消えないと説明しています。

実験に別のものをお試しください。私はNSObjectを試して、期待される結果を得ました。

インタフェース:

@interface ViewController : UIViewController 

@property (strong, nonatomic) NSObject * myString; 
@property (weak, nonatomic) NSObject * myPointer; 

@end 

実装: - Apple Developerまたはllvmメモリへの強いポインタが存在しない場合の文書で説明したように

@implementation ViewController 

@synthesize myString = _myString; 
@synthesize myPointer = _myPointer; 

- (void)viewDidLoad{ 

    [super viewDidLoad]; 

    self.myString = [[NSObject alloc] init]; 
    self.myPointer = self.myString; 
    self.myString = nil; 
    NSLog(@"myString: %@", self.myString); 
    NSLog(@"myPointer: %@", self.myPointer); 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
} 

@end 

弱いポインタはnilに設定されています。

__weakは、参照オブジェクトを有効に保たない参照を指定します。弱い参照は、オブジェクトへの強い参照がない場合にはnilに設定されます。

+0

華麗な答え、多くのありがとう。 – RGML

5

"Hello World!"の代わりにnilが表示されるはずです。

定数文字列は決して割り当てが解除されないので、 `@" Hello World! "決して逃げません。これはあなたの弱い参照が決してゼロに設定されない理由です。

+0

答えてくれてありがとうCaleb。しかし、私はあなたの言うことをテストするために別の弱いポインタを作成しました。残念ながら、ご覧のとおり、動作しません。 – RGML

+0

@Arkyxperience何が起こると思われますか? – Caleb

+5

弱い参照は、ターゲットの割り当てを解除するとnilに設定されます。これはARCの特徴であり、合成された弱いプロパティは決してぶら下がりポインタを保持しません。 – FellowMD