我刚刚开始进入iOS领域。我按照书中的一个例子,当我运行它时会抛出一个错误:
由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:' - [__ NSCFDictionary setObject:forKey:]:发送到不可变对象的mutating方法'
下面列出的示例代码:
@interface MyXMLElement : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *text;
@property (weak, nonatomic) MyXMLElement *parent;
@property (copy, nonatomic) NSMutableArray *children;
@property (copy, nonatomic) NSMutableDictionary *attributes;
@end
============================================
@implementation MyXMLElement
@synthesize name = _name;
@synthesize text = _text;
@synthesize parent = _parent;
@synthesize children = _children;
@synthesize attributes = _attributes;
-(id)init{
self = [super init];
if(self != nil){
NSMutableArray *childrenArray = [[NSMutableArray alloc]init];
self.children = [childrenArray mutableCopy];
NSMutableDictionary *attributesDictionary = [[NSMutableDictionary alloc]init];
self.attributes = [attributesDictionary mutableCopy];
}
return self;
}
@end
============================================
@interface MyXMLDocument : NSObject <NSXMLParserDelegate>
@property (nonatomic, strong) NSString *documentPath;
@property (nonatomic, strong) MyXMLElement *rootElement;
@property (nonatomic, strong) NSXMLParser *xmlParser;
@property (nonatomic, strong) MyXMLElement *currentElement;
-(BOOL)parseLocalXMLWithPath:(NSString *)paramLocalXMLPath;
@end
============================================
@implementation MyXMLDocument
@synthesize documentPath = _documentPath;
@synthesize rootElement = _rootElement;
@synthesize xmlParser = _xmlParser;
@synthesize currentElement = _currentElement;
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if (self.rootElement == nil){
MyXMLElement *root = [[MyXMLElement alloc] init];
self.rootElement = root;
self.currentElement = root;
} else {
MyXMLElement *newElement = [[MyXMLElement alloc] init];
newElement.parent = self.currentElement;
[self.currentElement.children addObject:newElement];
self.currentElement = newElement;
}
self.currentElement.name = elementName;
if ([attributeDict count] > 0){
//this line will throw out a exception.
[self.currentElement.attributes addEntriesFromDictionary:attributeDict];
}
}
答案 0 :(得分:2)
@property (copy, nonatomic) NSMutableDictionary *attributes;
这意味着合成方法-[MyXMLElement setAttributes:]
将使用-copy
方法复制其参数。这产生了一个不可变对象,即使参数是可变的。
尝试将其更改为:
@property (retain, nonatomic) NSMutableDictionary *attributes;
另外:此代码过于复杂且漏洞。
NSMutableDictionary *attributesDictionary = [[NSMutableDictionary alloc] init];
self.attributes = [attributesDictionary mutableCopy];
应该是:
self.attributes = [NSMutableDictionary dictionary];
这是什么书?太可怕了。