iphone - 我拥有的 NSManagedObject 被 main.m 释放了吗?

标签 iphone objective-c cocoa cocoa-touch

首先,在我的 Root View Controller viewDidLoad 中,我使用 NSManagedObjects 数组初始化一个 NSDictionary,如下所示:

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

现在,“self.tips”是我的 Root View Controller 上保留的 NSDictionary 属性,它被设置为包含 NSManagedObjects 数组。我愉快地继续使用该数据大约 5 分钟(包括将其传递给其他 View 的保留属性),直到我收到以下消息:

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

此时,在报错之后,真正崩溃之前,回溯如下:

#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

值得注意的是,里面没有我的代码。

0x3b300b0 上的打印对象显示:

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

最有趣的是,该地址上的 shell malloc_history:

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 

我对上面的解释是第一个 ALLOC 语句中的“[RootViewController viewDidLoad]”是我最初用数据填充提示 NSDictionary。然后在下面的 FREE 语句中,main.m 决定释放这些对象,即使它们位于我负责释放的保留 NSDictionary 中?

编辑每个请求,这里是 NSZombieEnabled 输出:

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

之后的回溯:

#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

上面引用的代码行 (/Users/***/RootViewController.m:32) 是:

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

从这里我可以看出我试图从“self.tips”访问的对象已经被释放(由谁?为什么?)

最佳答案

self.tips 还没有发布; [self.tips objectForKey:categoryNameString] 返回的提示有。它返回一个错误,而不是一个对象。必要时,Core Data 会自动对对象进行故障处理。

在定义 NSFetchRequest 时尝试将其放入:

[fetchRequest setReturnsObjectsAsFaults:NO];

这是正在发生的事情:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html ,如果您想了解更多信息。

关于iphone - 我拥有的 NSManagedObject 被 main.m 释放了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2375551/

相关文章:

iphone - 在 iOS 中将英制转换为公制?

iphone - 我可以限制 iPhone3G 使用我的 iPhone 应用程序吗?

ios - 是通过编程方式将设备iPhone或iPad

objective-c - NSMutableAttributedString 在 NSLinkAttributeName 时覆盖 NSForegroundcolor

c# - 使用 MonoMac 实现 NSOutlineViewDataSource

objective-c - NSURLCache 与自动释放的对象一起崩溃,但在其他情况下会泄漏

macos - 沙盒 Mac 应用程序可以读取/写入哪些非用户目录?

iphone - 我在哪里可以找到一个好的 iPhone/GWT/AppEngine 示例?

iphone - 输入带小数点的数值的最佳方法是什么?

iphone - 如何使用 ARC 处理 iOS 中的自动释放对象