NSManagedObjects that I have is released by main.m?

First, in the viewDidLoad root view controllers, I initialize an NSDictionary with NSManagedObjects arrays, for example:

- (void)viewDidLoad { [super viewDidLoad]; self.title = @"Decks"; UIBarButtonItem *browseButton = [[UIBarButtonItem alloc] initWithTitle:@"Browse" style:UIBarButtonItemStylePlain target:self action:@selector(loadBrowseView)]; self.navigationItem.rightBarButtonItem = browseButton; [browseButton release]; NSError *error = nil; if (![[self fetchedResultsController] performFetch:&error]) { } self.categories = [fetchedResultsController fetchedObjects]; NSMutableDictionary *tipsMutableDictionary = [[NSMutableDictionary alloc] init]; for (Category *category in self.categories) { NSMutableArray *tipsToSort = [NSMutableArray arrayWithArray:[[category valueForKey:@"tips"] allObjects]]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending: YES]; [tipsToSort sortUsingDescriptors: [NSArray arrayWithObject: sortDescriptor]]; [sortDescriptor release]; [tipsMutableDictionary setObject:[NSArray arrayWithArray:tipsToSort] forKey:[category name]]; } self.tips = tipsMutableDictionary; [tipsMutableDictionary release]; } 

Now "self.tips", which is a saved NSDictionary property on my root view controller, is configured to host NSManagedObjects arrays. I gladly continue to use this data for about 5 minutes (including passing it to other properties saved in view mode) until I receive the following message:

 malloc: *** error for object 0x3b300b0: double free 

At this point, after an error, but before the actual failure, the backtrace looks like this:

 #0 0x98152072 in malloc_error_break () #1 0x98153218 in szone_error () #2 0x9815334d in free_tiny_botch () #3 0x01b83064 in _PFDeallocateObject () #4 0x01b8d315 in -[_PFManagedObjectReferenceQueue _processReferenceQueue:] () #5 0x01bba9ba in _performRunLoopAction () #6 0x01d42252 in __CFRunLoopDoObservers () #7 0x01d4165f in CFRunLoopRunSpecific () #8 0x01d40c48 in CFRunLoopRunInMode () #9 0x0252d615 in GSEventRunModal () #10 0x0252d6da in GSEventRun () #11 0x002a3faf in UIApplicationMain () #12 0x00002830 in main (argc=1, argv=0xbfffef60) at /Users/***/main.m:14 

In particular, my code is not there.

The print object at 0x3b300b0 shows:

 <Tip: 0x3b300b0> (entity: Tip; id: 0x3b2ffe0 <x-coredata://10B4E6EE-ACF3-4316-AE10-6E06E8FFFF46/Tip/p9> ; data: <fault>) 

And the most interesting, shell malloc_history at this address:

 ALLOC 0x3b300b0-0x3b300ef [size=64]: thread_a0a3f500 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication _reportAppLaunchFinished] | CA::Transaction::commit() | CA::Context::commit_transaction(CA::Transaction*) | CALayerLayoutIfNeeded | -[CALayer layoutSublayers] | -[UILayoutContainerView layoutSubviews] | -[UINavigationController _startDeferredTransitionIfNeeded] | -[UINavigationController _startTransition:fromViewController:toViewController:] | -[UINavigationController _layoutViewController:] | -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] | -[UIViewController contentScrollView] | -[UIViewController view] | -[RootViewController viewDidLoad] | -[_NSFaultingMutableSet allObjects] | -[_NSFaultingMutableSet willRead] | -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] | +[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) allocWithEntity:] | _PFAllocateObject | malloc_zone_calloc ---- FREE 0x3b300b0-0x3b300ef [size=64]: thread_a0a3f500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopDoObservers | _performRunLoopAction | -[_PFManagedObjectReferenceQueue _processReferenceQueue:] | -[NSManagedObjectContext(_NSInternalAdditions) _forgetObject:propagateToObjectStore:] | -[NSManagedObjectContext(_NSInternalAdditions) _forgetObject:propagateToObjectStore:removeFromRegistry:] | CFDictionaryRemoveValue | CFRelease | _PFDeallocateObject | malloc_zone_free ALLOC 0x3b300b0-0x3b300cf [size=32]: thread_a0a3f500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopDoObservers | _performRunLoopAction | -[_PFManagedObjectReferenceQueue _processReferenceQueue:] | _PFDeallocateObject | free_tiny_botch | szone_error | start | _NSPrintForDebugger | -[NSManagedObject description] | +[NSString stringWithFormat:] | -[NSPlaceholderString initWithFormat:locale:arguments:] | _CFStringCreateWithFormatAndArgumentsAux | CFStringCreateMutable | _CFRuntimeCreateInstance | malloc_zone_malloc 

My interpretation of the above says that “[RootViewController viewDidLoad]” in the first ALLOC statement is that I first populated NSDictionary hints with data. Then, following the FREE statement, main.m decides to free these objects, even if they are in a saved NSDictionary, for which I am responsible for releasing?

EDIT Upon request, the output of NSZombieEnabled is output here:

 *** -[CFString retain]: message sent to deallocated instance 0x3b300b0 

Refund after that:

 #0 0x01d6a3a7 in ___forwarding___ () #1 0x01d466c2 in __forwarding_prep_0___ () #2 0x01cfd988 in CFRetain () #3 0x01cfd495 in CFArrayCreate () #4 0x01d406c3 in -[__NSPlaceholderArray initWithObjects:count:] () #5 0x01d4f6f8 in -[NSArray initWithArray:copyItems:] () #6 0x01d5c408 in +[NSArray arrayWithArray:] () #7 0x0000392f in -[RootViewController getRandomTip:] (self=0x3e1db40, _cmd=0x745b, sender=0x3e27d60) at /Users/***/RootViewController.m:32 #8 0x00299405 in -[UIApplication sendAction:to:from:forEvent:] () #9 0x002fcb4e in -[UIControl sendAction:to:forEvent:] () #10 0x002fed6f in -[UIControl(Internal) _sendActionsForEvents:withEvent:] () #11 0x002fdabb in -[UIControl touchesEnded:withEvent:] () #12 0x002b2ddf in -[UIWindow _sendTouchesForEvent:] () #13 0x0029c7c8 in -[UIApplication sendEvent:] () #14 0x002a3061 in _UIApplicationHandleEvent () #15 0x0252ed59 in PurpleEventCallback () #16 0x01d41b80 in CFRunLoopRunSpecific () #17 0x01d40c48 in CFRunLoopRunInMode () #18 0x0252d615 in GSEventRunModal () #19 0x0252d6da in GSEventRun () #20 0x002a3faf in UIApplicationMain () #21 0x00002830 in main (argc=1, argv=0xbfffef60) at /Users/***/main.m:14 

The indicated line of code above (/Users/***/RootViewController.m:32):

 NSArray *tipsArray = [NSArray arrayWithArray:[self.tips objectForKey:categoryNameString]]; 

All I can say from this is that the objects I'm trying to get from "self.tips" have already been released (by whom and why?)

+3
source share
2 answers

self.tips not been released; The tip returned by [self.tips objectForKey:categoryNameString] has. It returns an error, not an object. Core Data will automatically destroy objects if necessary.

Try entering this when defining NSFetchRequest:

 [fetchRequest setReturnsObjectsAsFaults:NO]; 

This is what happens: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html if you want to know more about this.

+1
source

Restart your program with the environment variable NSZombieEnabled set to YES . This will tell you when you double the release of the object and which object it is. In addition, you can debug this in the Tools with the Zombies tool.

+2
source

Source: https://habr.com/ru/post/1316102/


All Articles