7

Tôi đang sử dụng NSMutableDictionary và nhấn lỗi này:"đột biến phương pháp gửi đến đối tượng bất biến" mặc dù đối tượng là NSMutableDictionary

'NSInternalInconsistencyException', reason: '-[__NSCFDictionary removeObjectForKey:]: mutating method sent to immutable object' 

Dưới đây là các mã:

// Turn the JSON strings/data into objects 
    NSError *error; 
    NSMutableDictionary *invoiceDictFromReq = [[NSMutableDictionary alloc] init]; 
// invoiceDictFromReq = (NSMutableDictionary *)[NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error]; 
    invoiceDictFromReq = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error]]; 

NSLog(@"invoiceDictFromReq count: %i, key: %@, value: %@", [invoiceDictFromReq count], [invoiceDictFromReq allKeys], [invoiceDictFromReq allValues]); 

// Get values and keys from JSON response 
self.invoiceDict = [invoiceDictFromReq objectForKey:@"invoice"]; 
NSNumber *invoiceAmount = [self.invoiceDict objectForKey:@"amount"]; 
NSNumber *invoiceId = [self.invoiceDict objectForKey:@"id"]; 
NSNumber *invoiceNumber = [self.invoiceDict objectForKey:@"number"]; 
NSNumber *checkoutStarted = [self.invoiceDict objectForKey:@"checkoutStarted"]; 
NSNumber *checkoutCompleted = [self.invoiceDict objectForKey:@"checkoutCompleted"]; 
NSLog(@"amount: %@, id: %@, number: %@, started: %@, completed: %@", invoiceAmount, invoiceId, invoiceNumber, checkoutStarted, checkoutCompleted); 

Tất cả các giao diện điều khiển các bản ghi chỉ ra rằng dữ liệu là tốt. Đây là nơi mọi thứ bắt đầu bị phá vỡ. tôi vượt qua invoiceDict tài sản để điều khiển xem tiếp theo:

// Pass the invoice to checkoutViewController 
[checkoutViewController setInvoiceDict:self.invoiceDict]; 

Trong CheckoutViewController.m:

// Change invoice checkoutCompleted to true 
// [self.invoiceDict removeObjectForKey:@"checkoutCompleted"]; 
    [self.invoiceDict setObject:[NSNumber numberWithBool:YES] forKey:@"checkoutCompleted"]; 

Lỗi là tại [self.invoiceDict setObject...]. Tôi đảm bảo rằng tất cả các từ điển tôi sử dụng là NSMutableDictionary. Tôi để lại một số dòng nhận xét trong đoạn mã để cho thấy những thứ tôi đã thử và tôi đã đập vào một bức tường gạch. Tôi cho rằng tôi luôn có thể tạo một từ điển mới. Đó có phải là cách ưa thích để làm điều đó không?

Trả lời

9

Bạn đang phân bổ một từ điển trong invoiceDictFromReq và tiếp theo bạn đang tạo một từ điển khác, bạn đang tạo ra một bộ nhớ bị rò rỉ ở đó. Xóa dòng

NSMutableDictionary *invoiceDictFromReq = [[NSMutableDictionary alloc] init]; 

Nhưng vấn đề của bạn là bạn đang tạo ra một NSMutableDictionary nhưng bạn đang thiết để self.invoiceDict một cuốn từ điển bên mutableDictionary của bạn, mà không nhất thiết phải là một mutableDictionary quá. Thay đổi dòng

self.invoiceDict = [invoiceDictFromReq objectForKey:@"invoice"]; 

cho

self.invoiceDict = [NSMutableDictionary dictionaryWithDictionary:[invoiceDictFromReq objectForKey:@"invoice"]]; 
+0

Cảm ơn đã gợi ý nhưng nó vẫn mang lại cho tôi cùng một lỗi. Bây giờ, tôi có hoá đơnDictFromReq là một thuộc tính trong .h và được syntehsized in .m và đặt nó vào dữ liệu từ yêu cầu json là self.invoiceDictFromReq = [Từ điển NSMutableDictionary ...] – okysabeni

+1

Xin lỗi tôi đã thay đổi câu trả lời của tôi, nó không phải như vậy. Xem nếu bạn vẫn còn có vấn đề. Bạn không cần phải giữ lại hóa đơnDictFromReq vì nó là biến cục bộ, nhưng xóa dòng mà bạn tạo ra hóa đơnDictFromReq lần đầu tiên bởi vì bạn bị rò rỉ ở đó –

+0

:-). Khi tôi thấy, "Nhưng vấn đề của bạn là bạn đang tạo ra một NSMutableDictionary nhưng bạn đang thiết lập để self.invoiceDict một từ điển bên trong mutableDictionary của bạn, đó không nhất thiết phải là một mutableDictionary quá" Tôi biết bạn nhấn nó ngay tại chỗ. Thật ngốc nghếch của tôi. Cảm ơn đã chỉ ra điều đó. Tôi không nên giả định rằng trình phân tích cú pháp json nguyên gốc trả về NSMutableDictionary. Cám ơn rất nhiều! – okysabeni

15

NSJSONSerialization lợi nhuận đối tượng bất biến theo mặc định. Dưới đây là làm thế nào để có được từ điển có thể thay đổi từ phân tích cú pháp:

  • tùy chọn sử dụng NSJSONReadingMutableContainers

hoặc

  • sử dụng mutableCopy vào kết quả
+1

Chính xác những gì tôi đang tìm kiếm. Cảm ơn!!! – denikov

+0

Bạn không cần sử dụng mutableCopy, chỉ cần sử dụng kết quả.NSJSONReadingMutableContainers không chỉ làm cho mảng và từ điển trong kết quả có thể thay đổi được mà còn là kết quả của chính nó. – gnasher729

Các vấn đề liên quan