【问题标题】:need help about cocoa memory management [closed]需要有关可可内存管理的帮助[关闭]
【发布时间】:2012-11-12 13:01:31
【问题描述】:

我有一个类“TestA”并将其对象放在主函数的 NSMutable 字典中。第二个名为“ThreadClass”的类有一个线程。在这个线程中,我从字典中获取对象并使用它。当我运行这个程序时,仪器显示这个线程中的内存泄漏。但我不明白为什么内存泄漏,因为我没有使用任何新的或分配、复制或保留。我在主类中附加了我的程序的完整代码。需要有关内存管理的快速帮助。

我还有一个问题,如果我有一个以 NSString 作为数据成员的类。如果我将 this 的对象放在 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);
}

【问题讨论】:

  • 最简单的方法是使用 ARC。见:stackoverflow.com/questions/6385212/…
  • 感谢您的回复。但是在这里我没有在集合中创建自己的对象。这是自动释放对象。在主要我使用 [obj1->strTemp1 保留];在将对象添加到集合中之前,我将其引用计数增加到 1。如果我没有执行此步骤,则程序在线程循环中崩溃。我不明白为什么会这样。
  • 您可能需要阅读一般的内存管理以及属性。试试这个:developer.apple.com/library/mac/#documentation/General/…
  • 我已经阅读了关于内存管理的苹果文档。您能否指出上述代码中内存泄漏的缺陷。我需要上述代码的内存泄漏原因或解决方案。谢谢

标签: objective-c ios cocoa memory


【解决方案1】:

该代码有很多问题。远远超出内存管理。

我建议从Objective-C language guide 开始,然后转到iOS application architecture guideCocoa guide 用于OS X 应用程序。

一些错误的快速列表:

• 通常,您不应直接使用线程,并且任何线程都不应使用while(1) {...sleep(..);...} 轮询构造。应该使用运行循环、队列和 GCD。

retainCount 完全没用。不要叫它。详情请见http://www.whentouseretaincount.com

• 不要通过-&gt; 访问实例变量。两者都破坏了封装,并且在非常罕见的情况(有时是复制对象)之外,根本不是 Objective-C 中使用的模式。

• 这种模式没有意义:NSString *strKey =[NSString new]; strKey = @"abc";。它泄露了一个空的NSString 的实例(或者无论如何,如果它不是为了在 Foundation 中进行优化)。没有必要做第一个作业。

• 用main() 中的一堆代码构建一个应用程序,然后将控制权传递给 Cocoa 是没有意义的。编写基于 Foundation 的命令行工具或适当的 Cocoa 应用程序。

• 方法名称以小写字母开头并且是驼峰式。

• 看起来您可能正在走在 Cocoa 应用程序中做一些动画的道路上?如果是这样,您需要阅读Core Animation

• 如果这是一个新项目,请使用 ARC。

【讨论】:

    【解决方案2】:

    使用属性。在标题中:

    @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;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      相关资源
      最近更新 更多