-1

クラス「TestA」が1つあり、そのオブジェクトをメイン関数のNSMutable辞書に入れます。そして、スレッドを持つ "ThreadClass" という名前の 2 番目のクラス。このスレッドでは、辞書からオブジェクトを取得して使用しました。このプログラムを実行すると、このスレッドでメモリ リークが表示されます。しかし、新しい、割り当て、コピー、または保持を使用しなかったため、メモリがリークする理由がわかりません。プログラムの完全なコードをメインクラスに添付しました。メモリ管理について簡単なヘルプが必要です。

また、データ メンバーとして NSString を持つクラスがあるかどうかという質問もあります。このオブジェクトを NSMutabledictionary に配置した場合、このメモリ管理をどのように処理するか。ありがとう

#import <Cocoa/Cocoa.h>

@interface TestA : NSObject {

@public

    NSString *strTemp1;
}
@end

#import "TestA.h"

/////////////////////////////////////////////
//Implementation class

@implementation TestA

-(id)init
{
self = [super init];

if (self != nil) 
{       
    //strTemp1 = [[NSString alloc] init];
    //printf("\n Temp 1 %d \n", [strTemp1 retainCount]);
}
return self;
}
@end

//Thread Class

#import <Cocoa/Cocoa.h>

#import "TestA.h"
@interface ThreadClass : NSObject {

}
@end


#import "ThreadClass.h"

extern NSMutableDictionary *clData;

@implementation ThreadClass

-(void)Initialize
{
[NSThread detachNewThreadSelector:@selector(AnimateThread:) toTarget:self  withObject:nil];
printf("\n<<<<<<<<<<<<<<< Start Animator Thread Called >>>>>>>>>>>>>>>>>>>>>\n");
}

//==========================================================================
- (void) AnimateThread:(id) inObject
{
    NSAutoreleasePool *Pool = [[NSAutoreleasePool alloc] init];

NSDate *timeToSleep = [NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)5];

while (1) 
{
    //NSAutoreleasePool *threadPool = [[NSAutoreleasePool alloc] init];

    printf("\n Collection Size:%d \n", [clData count]);
    TestA *obj1 = [clData objectForKey:@"abc"];

    printf("\nThread Memory Counter:%d \n", [obj1 retainCount]);
    printf("\nThread Memory Counter:%s \n", [obj1->strTemp1 UTF8String]);

    //Sleep Thread for 5 Seconds
    [timeToSleep release];
    timeToSleep = [NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)5];
    [NSThread sleepUntilDate:(NSDate *)timeToSleep];
    //[timeToSleep release];

    //[threadPool release];
}

[Pool release];
}   
@end


//////////////////////////
Main Class


#import <Cocoa/Cocoa.h>
#import "TestA.h"
#import "ThreadClass.h"

NSMutableDictionary *clData = nil;
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


clData = [[NSMutableDictionary alloc] init];

//Creating Thread Class
ThreadClass *obj = [ThreadClass new];
[obj Initialize];
[obj release];

TestA *obj1 = [[TestA alloc] init];
NSString *strKey =[NSString new];
strKey = @"abc";

printf("\n Memory Counter:%d \n", [obj1 retainCount]);
printf("\n Memory Counter:%d \n", [obj1->strTemp1 retainCount]);

NSString *strTemp = @"Test Program";
obj1->strTemp1 = [NSString stringWithFormat:@"%s", [strTemp UTF8String]];
[obj1->strTemp1 retain];

printf("\n Memory Counter:%s \n", [obj1->strTemp1 UTF8String]);

[clData setObject:obj1 forKey:strKey];

printf("\nAfter Memory Counter:%d \n", [obj1 retainCount]);
printf("\nAfter Memory Counter:%d \n", [obj1->strTemp1 retainCount]);


[strKey release];
[obj1 release];

[pool release];

return NSApplicationMain(argc,  (const char **) argv);
}
4

2 に答える 2

2

そのコードにはたくさんの間違いがあります。メモリ管理をはるかに超えています。

Objective-C 言語ガイドから始めて、iOS アプリケーション アーキテクチャ ガイドまたはOS X アプリケーションのCocoa ガイドに進むことをお勧めします。

何が間違っているかの簡単なリスト:

• 一般に、スレッドを直接使用しないでください。また、スレッドでwhile(1) {...sleep(..);...}ポーリング構造を使用しないでください。代わりに実行ループ、キュー、および GCD を使用する必要があります。

retainCountまったく役に立たない。それを呼び出さないでください。詳細については、 http://www.whentouseretaincount.comを参照してください。

• 経由でインスタンス変数にアクセスしないでください->。どちらもカプセル化を破り、非常にまれな状況 (オブジェクトのコピーなど) 以外で Objective-C で使用されるパターンをまったく破りません。

• このパターンは意味がありません: NSString *strKey =[NSString new]; strKey = @"abc";. 空のインスタンスをリークしますNSString(または、Foundation での最適化がなければリークします)。その最初の割り当てを行う必要はありません。

• 一連のコードでアプリを構成し、main()制御を Cocoa に渡すことは意味がありません。Foundation ベースのコマンド ライン ツールまたは適切な Cocoa アプリを作成します。

• メソッド名は小文字で始まり、キャメルケースです。

• Cocoa アプリケーションで何らかのアニメーションを作成する道を進んでいるように見えますか? もしそうなら、あなたはCore Animationを読みたいと思うでしょう。

• これが新しいプロジェクトの場合は、ARC を使用します。

于 2012-11-12T16:08:31.123 に答える
0

プロパティを使用します。ヘッダー内:

@interface TestA : NSObject
{
   NSString *strTemp1_;
}
@property (nonatomic, copy) NSString* strTemp1;
@end

実装では:

@synthesize strTemp1=strTemp1_;

-(id)init
{
    self = [super init];

    if (self != nil) 
    {     
        strTemp1_=@"MyString";
    }
    return self;
}

//since your not using ARC you need to make sure that the property is NIL'd so that it will be released properly.
- (void) dealloc
{
    self.strTemp1=NULL;
}
于 2012-11-12T14:49:14.157 に答える