1

これは私のコードです、

import <Foundation/Foundation.h>

@interface SyncObjectInfo : NSObject
{
     NSString *strName;

}
@property(nonatomic,retain) NSString *strName;
-(void)returnRetainCount;

@end

#import "SyncObjectInfo.h"

@implementation SyncObjectInfo
@synthesize strName;
-(void)returnRetainCount
{

 self.strName=@"name";
 strName=@"name";
 NSLog(@"Que-1. what is the retainCount of self.strName = ___");
 NSLog(@"Que-2. what is the retainCount of      strName = ___");

 [self.strName retain];
 NSLog(@"Que-3. what is the retainCount of  self.strName= ___");

}

@end

保持カウントに混乱があるので...

-(void)returnRetainCount方法の質問(1、2、3)の答えを教えてください。理由を説明してください。

ありがとう

4

4 に答える 4

2

ステートメントに呼び出しを追加するように例を変更しretainCountました。これは特に有用な方法ではなく、一般的には避ける NSLog必要があることに注意してください。retainCount

詳細については、 http://whentouseretaincount.comを参照してください(詳細については、下にスクロールすることを忘れないでください)。

とにかく、これが私が実行したものです。[self.str retain]私がに変更したことに注意してください[self.strName retain]

#import <Foundation/Foundation.h>


@interface SyncObjectInfo : NSObject
{
     NSString *strName;
}

@property(nonatomic,retain) NSString *strName;

-(void)returnRetainCount;

@end

@implementation SyncObjectInfo
@synthesize strName;
-(void)returnRetainCount
{
 NSLog(@"Que-1. what is the retainCount of self.strName = %lu", [self.strName retainCount]);
 NSLog(@"Que-2. what is the retainCount of      strName = %lu", [strName retainCount]);

 [self.strName retain];
 NSLog(@"Que-3. what is the retainCount of  self.strName= %lu", [self.strName retainCount]);

}

@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        SyncObjectInfo *obj = [SyncObjectInfo new];

        [obj returnRetainCount];
    }
}

いずれの場合も、答えは0です。isと送信されたメッセージが無視されるため、これは予想されることstrNameです。したがって、toの呼び出しは無視されます。nilnil[self.strName retain]


ただし、strName次のコードを使用して、何かに設定した場合:

int main(int argc, char *argv[]) {
    @autoreleasepool {
        SyncObjectInfo *obj = [SyncObjectInfo new];

        obj.strName = @"Something";

        [obj returnRetainCount];
    }
}

次に、再実行すると、次のようになります。

Que-1. what is the retainCount of self.strName = 18446744073709551615
Que-2. what is the retainCount of      strName = 18446744073709551615
Que-3. what is the retainCount of  self.strName= 18446744073709551615

保持カウントは18446744073709551615です。これは、NSStringsがほとんどのオブジェクトとは異なる方法で処理されるためです。retainCountこれが、あまり役に立たない理由の1つです。


次のようにをに変更するNSStringと、NSURL次のようになります。

@interface SyncObjectInfo : NSObject
{
     NSURL *strName;
}

@property(nonatomic,retain) NSURL *strName;

// snip

int main(int argc, char *argv[]) {
    @autoreleasepool {
        SyncObjectInfo *obj = [SyncObjectInfo new];

        obj.strName = [NSURL URLWithString:@"http://stackoverflow.com"];

        [obj returnRetainCount];
    }
}

そして再実行すると、次のようになります。

Que-1. what is the retainCount of self.strName = 2
Que-2. what is the retainCount of      strName = 2
Que-3. what is the retainCount of  self.strName= 3

The first two cases are the same. The object returned by +URLWithString is retained but autoreleased and then assigned to the property and retained again. At some point in the future the autorelease pool will be flushed and the retain count will drop to 1.

The third value as we expect has gone up by one because of the explicit call to retain.


Your understanding from the Apple documentation that the retain count should be 1 (rather than 2 in questions 1 & 2) is technically incorrect but conceptually correct. The object has been autoreleased (effectively a promise that the object will be released in the near future).

We can investigate the effects of the autorelease pool by flushing the pool. I have modified the main function to flush the autorelease pool before calling returnRetainCount.

int main(int argc, char *argv[]) {
    @autoreleasepool {
        SyncObjectInfo *obj;

        @autoreleasepool {
            obj = [SyncObjectInfo new];

            obj.strName = [NSURL URLWithString:@"http://stackoverflow.com"];
        }

        [obj returnRetainCount];
    }
}

This time the output is:

Que-1. what is the retainCount of self.strName = 1 
Que-2. what is the retainCount of      strName = 1
Que-3. what is the retainCount of  self.strName= 2

This is more what you'd expect. So what is happening?

When the NSURL object is created by the URLWithString method it has a retain count of 1. However, the NSURL class needs to give up ownership of the object. If it called release on this object before returning it the retain count would reach 0 and the object would be deallocated before it is ever returned.

Instead the URLWithString method calls autorelease on the object. Autorelease adds the object to the autorelease pool. Basically, NSURL passes ownership to the autorelease pool with the understanding that the autorelease pool will release the object at some point in the near future (in an application the pool is flushed as part of the runloop cycle).

In the example above the object returned by URLWithString has a retain count of 1. Assigning it to the property increments the retain count by 1 (so it is now 2). We then flush the autorelease pool (by leaving the scope of the @autoreleasepool { } block and the retain count drops back to 1.

于 2013-01-31T07:10:24.067 に答える
1

Constant strings like this one @"Something" will have retain count as max unsigned int.
Because you can't release them as they are allocated in constant string pool.

于 2013-01-31T07:32:28.467 に答える
1
NSLog(@"Que-1. what is the retainCount of self.strName = %lu", [self.strName retainCount]);
retain count normal=2

NSLog(@"Que-2. what is the retainCount of      strName = %lu", [strName retainCount]);
retain count self=2

NSLog(@"Que-3. what is the retainCount of  self.strName= %lu", [self.strName retainCount]);
retain count self=3
于 2013-01-31T09:04:24.073 に答える
0

" retainCount"メソッドを介してObjectiveCオブジェクトに質問することで、いつでも自分で答えを見つけることができます。

EG: " NSLog( @"retain count for strName is %d", [self.strName retainCount]);"

この方法は「廃止された」と見なされ、出荷、製品コードbtwでは使用しないでください。

于 2013-01-31T06:50:21.990 に答える