2016-12-22 3 views
6

強く弱いのはプロパティ宣言で使われ、__strongと__weakはインスタンス変数の宣言で使われます... strongはオブジェクトをメモリに長くそれを所有していると弱いということは、他の誰かがそれを強く参照している限り、オブジェクトを記憶に残すと言う...そうですか?しかし、私はなぜプロパティのための弱いとインスタンス変数のための__weakが異なって動作するのか分からないのですか?ここで私は...なぜweak for propertyと__weakのインスタンス変数が異なって振る舞うのですか

@interface DemoViewController(){ 

    __weak NSArray *weakArray; 
    __strong NSArray *strongArray; 
    __weak NSString *weakString; 
    __strong NSString *strongString; 
} 

@property (weak) NSString *weakStringProperty; 
@property (strong) NSString *strongStringProperty; 

@property (weak) NSArray *weakArrayProperty; 
@property (strong) NSArray *strongArrayProperty; 

@end 

@implementation DemoViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    strongArray = [[NSArray alloc] initWithObjects:@"one",@"two", nil]; 
    weakArray = strongArray; 

    NSLog(@"Round:1 strongArray is %@.", strongArray); 
    NSLog(@"Round:1 weakArray is %@.", weakArray); 

    strongArray = nil; 

    NSLog(@"Round:2 strongArray is %@.", strongArray); 
    NSLog(@"Round:2 weakArray is %@.", weakArray); 

    self.strongArrayProperty = [[NSArray alloc] initWithObjects:@"one",@"two", nil]; 
    self.weakArrayProperty = self.strongArrayProperty; 

    NSLog(@"Round:1 strongArrayProperty is %@.", self.strongArrayProperty); 
    NSLog(@"Round:1 weakArrayProperty is %@.", self.weakArrayProperty); 

    self.strongArrayProperty = nil; 

    NSLog(@"Round:2 strongArrayProperty is %@.", self.strongArrayProperty); 
    NSLog(@"Round:2 weakArrayProperty is %@.", self.weakArrayProperty); 


    strongString = [[NSString alloc]initWithFormat:@"instanceVariable"]; 
    weakString = strongString; 

    NSLog(@"Round:1 strongString is %@.", strongString); 
    NSLog(@"Round:1 weakString is %@.", weakString); 

    strongString = nil; 

    NSLog(@"Round:2 strongString is %@.", strongString); 
    NSLog(@"Round:2 weakString is %@.", weakString); 

    self.strongStringProperty = [[NSString alloc]initWithFormat:@"Property"]; 
    self.weakStringProperty = self.strongStringProperty; 

    NSLog(@"Round:1 strongStringProperty is %@.", self.strongStringProperty); 
    NSLog(@"Round:1 weakStringProperty is %@.", self.weakStringProperty); 

    self.strongStringProperty = nil; 

    NSLog(@"Round:2 strongStringProperty is %@.", self.strongStringProperty); 
    NSLog(@"Round:2 weakStringProperty is %@.", self.weakStringProperty); 

} 
@end 

そして、ここでは、彼らは弱いを参照されたオブジェクトの後に結果のログ

Round:1 strongArray is (
    one, 
    two 
). 
Round:1 weakArray is (
    one, 
    two 
). 
Round:2 strongArray is (null). 
Round:2 weakArray is (null). 


Round:1 strongArrayProperty is (
    one, 
    two 
). 
Round:1 weakArrayProperty is (
    one, 
    two 
). 
Round:2 strongArrayProperty is (null). 
Round:2 weakArrayProperty is (
    one, 
    two 
).   —??? 

Round:1 strongString is instanceVariable. 
Round:1 weakString is instanceVariable. 
Round:2 strongString is (null). 
Round:2 weakString is (null). 


Round:1 strongStringProperty is Property. 
Round:1 weakStringProperty is Property. 
Round:2 strongStringProperty is (null). 
Round:2 weakStringProperty is Property. ——?? 

弱いインスタンス変数の印刷(ヌル)ともにnilに設定されていると不思議に思ったものですこれは期待どおりですが、弱いプロパティーweakStringPropertyとweakArrayPropertyの両方が以前の値を表示していて、strongStringPropertyとstrongArrayPropertyを強く指していたように振る舞うのはなぜだろうか?

感謝:)

+0

ラウンド2ではstrongArrayPropertyとweakArrayPropertyを(null)として取得できますが、ラウンド2のweakStringPropertyはまだ「プロパティ」です。 ARCが技術的にこれを処理する必要があるので、これは非常に奇妙です。 PS-私はこれを私のコンピュータで走らせました。 –

+0

私は主なメソッドは、アプリケーションを実行するautoreleaseプールを実行しているので、弱いプロパティが保持されている理由だと思う。自動解放プールのため、弱いプロパティはすぐにはnilに設定されません。しかし、私はviewDidAppearとdidReceiveMemoryWarning(メモリ警告をシミュレートして)にアクセスしようとしましたが、それはまだnilにならなかった。 –

+0

奇妙な!!このコードを実際のデバイスで実行すると、弱いインスタンス変数と弱いプロパティの両方に期待される結果が得られました。つまり、シミュレータだけで問題が発生しています。とにかくThxsシミュレータ上の@Kunal Shrivastava – Dipika

答えて

1

weakStringPropertyそれは財団はまだそれを保持しているためnilではありません。

[[NSString alloc]initWithFormat:@"Property"]を呼び出したとき、Foundationは文字列をNSTaggedPointerStringとしてインテグレーションすることにしました。この文字列は、将来の使用のために保持されています。あなたは、クラスをロギングすることで、これを検証することができます。

NSLog(@"kindof: %@", [self.weakStringProperty class]); 

私はすべての基準は、システムがこれらの文字列を作成することを決定するために使用していますが、長さと可変性が要因であるかわからないんだけど。以下のいずれかがあなたの望む結果を得るでしょう。あなたがそれらを非アトミック宣言していなかったので、

// Longer string 
self.strongStringProperty = [[NSString alloc]initWithFormat:@"Property la la la"]; 

// Mutable string 
self.strongStringProperty = [[NSMutableString alloc]initWithFormat:@"Property"]; 
1

あなたの性質は、アトミックです。 Atomicプロパティは保持され、オートレリースされたオブジェクトを返します。そのため、オブジェクトはオートリリースプールに残り、viewDidLoadメソッドを終了するまで保持されます。

@property (weak, nonatomic, readwrite) NSString *weakStringProperty; 

に例えば変更し、あなたが期待する結果を得る可能性が高くなります。後で別のメソッドでプロパティをチェックすると、弱いプロパティがなくなる可能性があります。

しかし、iOSは、決してリリースされないオブジェクトを頻繁に作成します。たとえば、空のNSArrayオブジェクトがあります。これは決してリリースされることはありません。多くのNSNumberオブジェクト、短い文字列、@YES、@NOなどと同じです。あなたがそれがそうであると思うときにオブジェクトが割り当て解除されるという保証はないので、弱いオブジェクトがゼロになることは保証されません。

+0

...私はあなたがやりたいと言った変更を試みました...プロパティはまだviewDidLoadとviewWillAppearではnilに設定されていませんでしたが、viewDid Appearではnilに設定されます。しかし、奇妙なことは、私が弱い性格のものがすべて、nilに設定され、期待される結果を記録した後に、nilに設定されていたデバイスでこれを実行する場合です。とにかくthxs :) – Dipika

関連する問題