我正在尝试学习objective-c(我对此非常新)并且我在内存管理方面存在问题......
我正在开发一款使用TouchXML的iPad应用程序。
我创建了扩展CXMLDocument的类,并通过读取一些内容并保存到属性中进行初始化。
这是我的代码(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
稍后在另一节课中我做了:
- (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);
}
它给了我很多“指针被释放没有分配”的错误...... 如果我注释掉上面的NSLog调用或者只记录manifest.title属性,那么事情就会改变。 Project没有使用ARC,所以我确定我在内存管理方面做错了。
有人可以帮我理解我做错了吗?谢谢!
答案 0 :(得分:5)
该代码没有任何明显错误会导致malloc错误。最好的猜测是,CXMLDocument类/库中存在错误,或者您使用它时出现了一些错误。
请注意,“未分配的指针”表示有人在指向未首先分配的内存的指针上有效地调用free()
(或dealloc
)。它通常会为您提供一个断点,您可以设置断点,然后回溯确切的位置。
一些意见:
(1)不要以这种方式@ try / @ catch。只是不要抓住。您使用的模式将隐藏任何错误。在iOS / Cocoa中,异常并不是可以恢复的。
(2)您可以直接从文件创建NSString
实例;无需先通过NSData
加载。
(3)你应该使用ARC。