2012-11-12 25 views
-1

我有一個類「TestA」並將它的對象放在主函數的NSMutable字典中。第二類名稱爲「ThreadClass」,它具有一個線程。在這個線程中,我從字典中獲取對象並使用它。當我運行該程序時,儀器向我顯示了此線程中的內存泄漏。但我不明白爲什麼內存泄漏,因爲我沒有使用任何新的或分配,複製或保留。我附上了我的程序的完整代碼與主類。需要關於內存管理的qucik幫助。需要關於可可內存管理的幫助

我也有一個問題,如果我有一個有NSString作爲數據成員的類。如果我把這個對象放在NSMutableDictionary中,那麼我如何處理這個內存管理。 thanx

#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); 
} 
+1

最簡單的方法是使用ARC。見:http://stackoverflow.com/questions/6385212/how-does-the-new-automatic-reference-counting-mechanism-work – tillerstarr

+0

thanx爲您的答覆。但是在這裏我沒有在收藏中創建自己的對象。這是autorelease對象。在主要我用[obj1-> strTemp1 retain];在集合中添加對象之前,我將其引用計數增加爲1.如果我沒有執行此步驟,則程序在線程循環中崩潰。我不明白爲什麼會發生這種情況。 –

+0

您可能需要閱讀內存管理以及屬性。試試這個:https://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html – NikosM

回答

0

使用屬性。在標題:

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

在實施:

@synthesize strTemp1=strTemp1_; 

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

    if (self != nil) 
    {  
     [email protected]"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; 
} 
2

有一噸的東西錯碼。超越內存管理。

我會建議從Objective-C language guide開始,然後轉到iOS application architecture guideCocoa guide的OS X應用程序。

的一些東西的快速列表是錯誤的:

•在一般情況下,你不應該直接使用線程,任何線程不應該使用一個while(1) {...sleep(..);...}投票結構。應該使用運行循環,隊列和GCD。

retainCount完全沒用。別叫它。詳情請參閱http://www.whentouseretaincount.com

•不要通過->訪問實例變量。除了非常罕見的情況(有時候複製對象)外,兩者都打破了封裝並且完全不是在Objective-C中使用的模式。

•這種模式沒有意義:NSString *strKey =[NSString new]; strKey = @"abc";。它泄漏一個空的NSString的實例(或者,如果不是在基金會中進行優化的話)。沒有必要做第一項任務。

•用main()中的一堆代碼構造應用程序,然後將控件傳遞給Cocoa沒有任何意義。要麼寫一個基於基礎的命令行工具或適當的Cocoa應用程序。

•方法名稱以小寫字母開頭並以camelCased開頭。

•看起來你可能會在Cocoa應用程序中做一些動畫的路徑?如果是這樣,你需要閱讀Core Animation

•如果這是一個新項目,請使用ARC。