内存管理与代码

时间:2011-12-19 16:34:50

标签: objective-c cocos2d-iphone

嗨我有2个班级,其中一个是plisreader,它遵循代码

//
//  PlistReader.h
//  NationalAntemsAndFlags
//
//  Created by mac on 12/17/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "CountryClass.h"

@interface PlistReader : NSObject
{
    NSDictionary *temp;
}
@property (nonatomic,retain) NSDictionary *temp;

-(int)LengthOfPList;
-(id)GetTheObjectById:(NSString*)ObjId;
-(void)initWithFileName:(NSString*)fileName;
- (id)getCountryInfoById:(int)id;
@end

//实施文件

//
//  PlistReader.m
//  NationalAntemsAndFlags
//
//  Created by mac on 12/17/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "PlistReader.h"

@implementation PlistReader
@synthesize temp;


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

    }
    return self;
}
-(void)initWithFileName:(NSString*)fileName
{
    // Data.plist code
    // get paths from root direcory

    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:[fileName stringByAppendingString:@"plist"]];

    // check to see if Data.plist exists in documents
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
    {
        // if not in documents, get property list from main bundle
        plistPath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"];
    }

    // read property list into memory as an NSData object
    NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
    NSString *errorDesc = nil;
    NSPropertyListFormat format;
    // convert static property liost into dictionary object
    temp =(NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
    if (!temp)
    {
        NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
    }
    // assign values

}

-(int)LengthOfPList
{
    return temp.count;
}
-(id)GetTheObjectById:(NSString*)ObjId
{

   return [temp objectForKey:ObjId];

}
-(id)getCountryInfoById:(int)objId
{

    NSString *objsId = [NSString stringWithFormat:@"%d",objId];
    NSDictionary *CDirectory = (NSDictionary*) [self GetTheObjectById:objsId];
    int count = CDirectory.count;
    if(count>0)
    {
        CountryClass *objCountry = [[CountryClass alloc] init];   
        objCountry.Name= [CDirectory objectForKey:@"Name"];
        objCountry.LocationX =[[CDirectory objectForKey:@"PositionX"] intValue];
        objCountry.LocationY = [[CDirectory objectForKey:@"PositionY"] intValue];
        objCountry.ImageUrl = [CDirectory objectForKey:@"ImageUrl"];
        objCountry.AnthemUrl =[CDirectory objectForKey:@"AnthemUrl"];
        objCountry.ShortDetail =[CDirectory objectForKey:@"short Info"];
        objCountry.completeDetails = [CDirectory objectForKey:@"Details"];
        id ObjCountryInfo= objCountry;
        [objCountry release];
        return ObjCountryInfo;
    }
    return NULL;
}

-(void)dealloc
{
    NSLog(@"dealloc plist");
    [temp release];
    [super dealloc];
}




@end

另一个是具有以下代码

的国家/地区类
//
//  CountryClass.h
//  NationalAntemsAndFlags
//
//  Created by mac on 12/17/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface CountryClass : NSObject
{
    NSString *Name ;
    NSString *ImageUrl;
    NSString *AnthemUrl;
    NSString *ShortDetail;
    NSString *completeDetails;
    int LocationX ;
    int LocationY ;


}
@property (nonatomic,retain) IBOutlet NSString *Name;
@property (nonatomic,retain) IBOutlet NSString *ImageUrl;
@property (nonatomic,retain) IBOutlet NSString *AnthemUrl;
@property (nonatomic,retain) IBOutlet NSString *ShortDetail;
@property (nonatomic,retain) IBOutlet NSString *completeDetails;
@property (nonatomic) IBOutlet int LocationY;
@property (nonatomic) IBOutlet int LocationX;



@end

实施档案

//
//  CountryClass.m
//  NationalAntemsAndFlags
//
//  Created by mac on 12/17/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "CountryClass.h"

@implementation CountryClass

@synthesize Name,ImageUrl,AnthemUrl,ShortDetail,completeDetails,LocationX,LocationY;


@end

所以我在我的场景中这样称呼

-(void)LoadData:(int)countryId
{
    CId = countryId;
    PlistReader *pList =[[PlistReader alloc]init];
    [pList initWithFileName:@"CountryDetails"];   

    CountryClass *objcountry = (CountryClass*) [pList getCountryInfoById:countryId];

    NSString *tempLongDetails = objcountry.completeDetails;
    NSString *tempShortDetails = objcountry.ShortDetail;
    NSString *fileName =  objcountry.ImageUrl ;
    CCSprite *flag ;

    NSString * fullPath = [[NSBundle mainBundle] pathForResource: [fileName stringByDeletingPathExtension]
                                                             ofType: [fileName pathExtension]
                                                           inDirectory: @"CountryFlags"];


    NSLog(fullPath);
    if (fullPath)
    {
       UIImage  *theImage = [UIImage imageWithContentsOfFile: fullPath];
       if (theImage)
       {
            flag = [CCSprite spriteWithCGImage: [theImage CGImage] key: fileName];
           // flag = [CCSprite spriteWithFile:fileName];
            flag.position = ccp(200, 265);
           flag.scale = .255;
       }
    }



    TextViewTopFlagData = [[UITextView alloc]init];
    TextViewTopFlagData.text = tempShortDetails;
    TextViewTopFlagData.frame = CGRectMake(260,17, 105, 75);
    TextViewTopFlagData.backgroundColor = [UIColor clearColor];
    [TextViewTopFlagData setEditable:NO];


    TextViewDownFlagData = [[UITextView alloc]init];
    TextViewDownFlagData.text = tempLongDetails;
    TextViewDownFlagData.frame = CGRectMake(22,240, 242, 61);
    TextViewDownFlagData.backgroundColor = [UIColor clearColor];
    [TextViewDownFlagData setEditable:NO];
    [[[CCDirector sharedDirector]openGLView]addSubview:TextViewTopFlagData];
    [[[CCDirector sharedDirector]openGLView]addSubview:TextViewDownFlagData];
    [self addChild:flag];

}

@end

但是在函数结束时objcountry将为空或者没有参考可以任何人解释我为什么这是幸福的

2 个答案:

答案 0 :(得分:0)

只是瞥了一眼你的代码,这突然转向了我:

temp =(NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];

您需要保留它,如下所示:

temp = [(NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc] retain];

这对你的bug没有帮助,但是最好不保留具有可变子类的属性(即NSString具有NSMutableString,NSSet具有NSMutableSet,NSDictionary具有NSMutableDictionary)。相反,copy对他们来说更好(更安全)。即。

@property (nonatomic, retian) NSString *name; // worse
@property (nonatomic, copy) NSString *name; // better

由于这些原因,请阅读the accepted answer here

答案 1 :(得分:0)

这个函数是否有意义返回(id)而不是(CountryClass *)

-(id)getCountryInfoById:(int)objId
{

    NSString *objsId = [NSString stringWithFormat:@"%d",objId];
    NSDictionary *CDirectory = (NSDictionary*) [self GetTheObjectById:objsId];
    int count = CDirectory.count;
    if(count>0)
    {
        CountryClass *objCountry = [[CountryClass alloc] init];   
        objCountry.Name= [CDirectory objectForKey:@"Name"];
        objCountry.LocationX =[[CDirectory objectForKey:@"PositionX"] intValue];
        objCountry.LocationY = [[CDirectory objectForKey:@"PositionY"] intValue];
        objCountry.ImageUrl = [CDirectory objectForKey:@"ImageUrl"];
        objCountry.AnthemUrl =[CDirectory objectForKey:@"AnthemUrl"];
        objCountry.ShortDetail =[CDirectory objectForKey:@"short Info"];
        objCountry.completeDetails = [CDirectory objectForKey:@"Details"];
        id ObjCountryInfo= objCountry;
        [objCountry release];
        return ObjCountryInfo;
    }
    return NULL;
}

您的问题是在返回objCountry并将其引用到id-object之前释放它。

    id ObjCountryInfo= objCountry;
    [objCountry release];
    return ObjCountryInfo;

我的建议是不要在这个方法中释放countryObject(当你完成它时释放它)并将return-type更改为CountryClass *