Управление памятью с помощью кода - PullRequest
0 голосов
/ 19 декабря 2011

привет, у меня есть 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 голосов
/ 22 декабря 2011

Имеет ли смысл, что эта функция возвращает (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-объект.

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

Мое предложение состоит в том, чтобы не освобождать countryObject в этом методе (освободить его, когда вы закончили с ним) и изменять тип возвращаемого значения на CountryClass *

0 голосов
/ 19 декабря 2011

Просто взглянув на твой код, это выскакивает у меня:

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

Вы должны сохранить его, как это:

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

Это не поможет вашей ошибке, но рекомендуется не сохранять свойства, которые имеют изменяемый подкласс (то есть NSString имеет NSMutableString, NSSet имеет NSMutableSet, NSDictionary имеет NSMutableDictionary). Лучше (безопаснее) вместо них copy. т.е.

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

По причинам почему, прочитайте принятый ответ здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...