【问题标题】:why did it cause a "mutating method sent to immutable object" exception?为什么会导致“发送到不可变对象的变异方法”异常?
【发布时间】:2012-03-06 08:24:17
【问题描述】:

我刚刚开始进入 iOS 领域。我按照书中的一个例子,运行时抛出了一个错误:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object”

下面列出的示例代码:

@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];
    }
}

【问题讨论】:

  • 在哪一行抛出错误?

标签: objective-c ios


【解决方案1】:
@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];

这是什么书?太可怕了。

【讨论】:

  • 感谢您的帮助,此错误已修复,但我得到了一个新错误:Error Domain=NSXMLParserErrorDomain Code=5 "The operation could not be completed. (NSXMLParserErrorDomain error 5.)"
  • xml文件内容很简单:
  • xml文件末尾有格式错误,这本书真的很糟糕。
  • 哈!使用完全相同的代码,我遇到了完全相同的问题。这本书是my.safaribooksonline.com/9781449398002 iOS 4 Programming Cookbook 作者:Vandad Nahavandipoor 出版商:O'Reilly Media, Inc. Pub。日期:2011 年 2 月 1 日 印刷 ISBN-13:978-1-4493-8822-5 印刷版页数:640 下载书 [15 代币]:PDF、Mobi、ePub 订户评级:[7 评级] 订户评论
猜你喜欢
  • 2011-08-13
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多