3

私はObjective-Cを初めて使用し、メモリ管理を読んでいました。NSAutoreleasePoolで少し遊んでみましたが、どういうわけかオブジェクトが解放されません。

基本的にNSString*nameを設定するsetterとgetterを持つクラスがあります。プールを解放した後、オブジェクトをNSLogしようとしましたが、それでも機能しますが、そうではないと思いますか?

@interface TestClass : NSObject
{
    NSString *name;
}

- (void) setName: (NSString *) string;
- (NSString *) name;


@end

@implementation TestClass   

- (void) setName: (NSString *) string
{
        name = string;
}  

- (NSString *) name
{
    return name;
}

@end

int main (int argc, const char * argv[]) {

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

TestClass *var = [[TestClass alloc] init];

[var setName:@"Chris"];
[var autorelease];
[pool release];

// This should not be possible?
NSLog(@"%@",[var name]);


return 0;
}
4

2 に答える 2

5

ポインタ変数を離すと、それが指しているメモリを再割り当てできることをOSに通知します。ポインタは引き続きそのメモリを指し、再割り当てされるまで、オブジェクトの残りが含まれます。再割り当てされると、nameメソッドを呼び出そうとしても機能しなくなります。

于 2010-05-07T12:42:08.007 に答える
2

コードにはいくつかの問題があります。まず、インスタンス変数に格納されている文字列copyも実行しません。したがって、文字列をプロパティに保存した人が文字列を解放すると、ぶら下がっている参照が残ります。やったほうがいいretainname

- (void) setName: (NSString*) aName {
    if( name != aName ) {
        if( name ) [name release];
        name = [aName retain];    // or copy
    }
}

または、最初からプロパティを使用します。

また、オブジェクト参照をインスタンス変数に保持する場合は、deallocメソッドの適切な定義を提供する必要があります。

- (void) dealloc {
    self.name = nil;
    [super dealloc];
}

最後に、オブジェクトの割り当てが解除されたからといって、前のインスタンスのメモリが無効になっているわけではありません。元のプログラムは、ぶら下がっている参照(var)でメソッドを呼び出している可能性があります。これは、運が良ければここで機能します。(特に、to(autoreleaseは参照を自動的にに設定しませんnil)。

于 2010-05-07T12:44:28.507 に答える