0

I'm trying to learn objective-c (I'm very new to that) and I have issues with memory management...

I'm developing an iPad app that uses TouchXML.

I've created my class that extends CXMLDocument and does some initialisation by reading some contents and saving into properties.

Here is my code (SimpleManifest.h):

@interface SimpleManifest : CXMLDocument {
    CXMLNode *_defaultOrganization;
    NSString *_title;

    NSDictionary *dictionary;
}

@property (readonly) CXMLNode *defaultOrganization;
@property (readonly) NSString* title;

- (id) initWithPath:(NSString *)path options:(NSUInteger)options error:(NSError **)error;

@end

(SimpleManifest.m):

#import "SimpleManifest.h"
#import "CXMLNode_XPathExtensions.h"

@implementation SimpleManifest

- (id) initWithPath:(NSString *)path options:(NSUInteger)options error:(NSError **)error
{
    /*
    NSURL *theURL = [[[NSURL alloc] initFileURLWithPath:path] autorelease];
    self = [self initWithContentsOfURL:theURL options:options error:error];
    */

    NSData *data   = [NSData dataWithContentsOfFile:path];
    NSString *s = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];

    self = [self initWithXMLString:s options:options error:error];

    if (self==nil) return nil;

    // load main props

    dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                  @"http://www.imsglobal.org/xsd/imscp_v1p1", @"imscp",
                  @"http://ltsc.ieee.org/xsd/LOM", @"lom", nil];


    // defualt organization
    @try {


        CXMLNode *orgsElem = [[[self childAtIndex:0] nodesForXPath:@"//imscp:organizations" namespaceMappings:dictionary error:nil] objectAtIndex:0];
        NSString *xpath = [NSString stringWithFormat:@"//imscp:organization[@identifier='%@']", [[orgsElem attributeForName:@"default"] stringValue]];

        _defaultOrganization = [[[self childAtIndex:0] nodesForXPath:xpath namespaceMappings:dictionary error:nil] objectAtIndex:0];


        /*
        NSArray *nodes = [[self childAtIndex:0] nodesForXPath:@"//imscp:organizations" namespaceMappings:dictionary error:nil];
        NSString *xpath = [NSString stringWithFormat:@"//imscp:organization[@identifier='%@']", [[[nodes objectAtIndex:0] attributeForName:@"default"] stringValue]];
        _defaultOrganization = [[[self childAtIndex:0] nodesForXPath:xpath namespaceMappings:dictionary error:nil] objectAtIndex:0];
        */

        CXMLNode *titleElem = [[[self childAtIndex:0]
                                  nodesForXPath:@"//lom:general/lom:title/lom:string"
                                  namespaceMappings:dictionary
                                  error:nil] objectAtIndex:0];

        _title = [[titleElem stringValue] copy];

    } @catch (NSException * e){
        self = nil;
        return nil;
    }


    return self;
}
@end

Later on in another class I do:

- (BOOL) isValidSCORMLesson:(NSString*) path {
    NSString *manifPath = [path stringByAppendingPathComponent:@"imsmanifest.xml"];
    if (![[NSFileManager defaultManager] fileExistsAtPath: manifPath isDirectory: NO])
        return NO;

    SimpleManifest *manifest = [[[SimpleManifest alloc] initWithPath:manifPath options:0 error:nil] autorelease];
    NSLog(@"%@", manifest.defaultOrganization);
    NSLog(@"%@", manifest.title);

    return (manifest!=nil);
}

It gives me tons of "pointer being freed was not allocated" errors... The thing changes if I comment out the NSLog calls above or just log the manifest.title property. Project is not using ARC, so I'm sure I'm doing something wrong with memory management.

Can someone please help me understand where I'm doing wrong? Thanks!

4

1 回答 1

5

该代码没有任何明显的错误会导致 malloc 错误。最好的猜测是 CXMLDocument 类/库中存在错误,或者您使用它的方式存在错误。

请注意,“未分配被释放的指针”意味着有人调用free()(或dealloc有效地)指向最初未分配的内存的指针。它通常会为您提供一个可以设置的断点,然后您可以回溯它发生的确切位置。

一些评论:

(1) 不要以这种方式@try/@catch。根本不抓。您使用的模式将隐藏任何错误。在 iOS/Cocoa 中,异常并不意味着可以恢复。

(2) 可以NSString直接从文件创建实例;无需先通过加载NSData

(3) 你应该使用ARC。

于 2013-06-03T15:33:24.317 回答