I created an array using the following code. After the 12 images have no longer needed, I set the imageArray to nil and reload a new set of images into this array. When I run the app in instruments I can see a memory buildup issue. I also ran heapshots and it shows 12 images still lingering even after I set the array to nil. I also tried to init this array in its own autorelease pool thinking it was somehow created on a separated thread below the main thread. That did not work either. Any ideas?
ViewController.h
#property (strong, nonatomic) NSMutableArray *imageArray;
ViewController.m
- (void) firstSetOfImages{
imageArray= [[NSMutableArray alloc] initWithObjects:wordImage1, wordImage2, wordImage3, wordImage4, wordImage5, wordImage6, wordImage7, wordImage8, wordImage9, wordImage10, wordImage11, wordImage12, nil];
}
- (void) clearImages{
[self setImageArray:nil];
[imageArray removeAllObjects];
[self secondSetOfImages];
}
- (void) secondSetOfImages{
imageArray= [[NSMutableArray alloc] initWithObjects:wordImage1, wordImage2, wordImage3, wordImage4, wordImage5, wordImage6, wordImage7, wordImage8, wordImage9, wordImage10, wordImage11, wordImage12, nil];
}
Here is an example of 1 heapshot taken in between the loading of 1 set of 12 images and the second set of 12 images.
Snapshot Timestamp Heap Growth # Persistent
Heapshot 3 00:39.457.174 53.02 KB 800
< non-object > 26.05 KB 277
UIImageView 3.38 KB 36
CFDictionary (mutable) 3.38 KB 72
CFBasicHash (key-store) 2.83 KB 73
CFBasicHash (value-store) 2.83 KB 73
NSPathStore2 2.25 KB 12
CGImageReadRef 1.88 KB 12
CALayer 1.69 KB 36
CGImage 1.62 KB 13
CFNumber 1.31 KB 84
CGImagePlus 1.31 KB 12
CFData 1.12 KB 24
CGImageProvider 768 Bytes 12
CGDataProvider 720 Bytes 5
UIImage 576 Bytes 12
CFString (immutable) 416 Bytes 13
CFArray (mutable-variable) 384 Bytes 12
CGImageReadSessionRef 192 Bytes 12
_ UIImageViewExtendedStorage 192 Bytes 4
__NSArrayM 160 Bytes 5
CFDictionary (immutable) 48 Bytes 1
EDIT:
I modified the code and made the arrays an ivar. I took another sample of Allocations in Instruments. Below are is a more detailed display of my heapshots. I took a heapshot every time I reset my array with 12 new images. Every heapshot is has a heapgrowth of about 35kb.
Snapshot Timestamp Heap Growth # Persistent
Heapshot 4 00:58.581.296 35.63 KB 680
< non-object > 13.02 KB 220
CFDictionary (mutable) 3.38 KB 72
CFBasicHash (key-store) 2.81 KB 72
CFBasicHash (value-store) 2.81 KB 72
NSPathStore2 2.28 KB 12
CGImageReadRef 1.88 KB 12
CGImage 1.50 KB 12
CFNumber 1.31 KB 84
CGImagePlus 1.31 KB 12
CFData 1.12 KB 24
UIImageView 1.12 KB 12
CGImageProvider 768 Bytes 12
UIImage 576 Bytes 12
CALayer 576 Bytes 12
CFString (immutable) 384 Bytes 12
CFArray (mutable-variable) 384 Bytes 12
CGImageReadSessionRef 192 Bytes 12
CGDataProvider 144 Bytes 1
_UIImageViewExtendedStorage96 Bytes 2
__NSArrayM 32 Bytes 1
Here is the stacktrace of one of those Persistent items in UIImage. It doesn't point to a specific line of code that created it. Not sure where to go from here?
24 FourGameCenter 0x4b4bf
23 FourGameCenter 0x4b538
22 UIKit UIApplicationMain
21 GraphicsServices GSEventRunModal
20 CoreFoundation CFRunLoopRunInMode
19 CoreFoundation CFRunLoopRunSpecific
18 CoreFoundation __CFRunLoopRun
17 CoreFoundation __CFRunLoopDoSource1
16 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
15 GraphicsServices PurpleEventCallback
14 GraphicsServices _PurpleEventCallback
13 UIKit _UIApplicationHandleEvent
12 UIKit -[UIApplication sendEvent:]
11 UIKit -[UIWindow _sendTouchesForEvent:]
10 UIKit -[UIControl touchesEnded:withEvent:]
9 UIKit -[UIControl(Internal) _sendActionsForEvents:withEvent:]
8 UIKit -[UIControl sendAction:to:forEvent:]
7 UIKit -[UIApplication sendAction:toTarget:fromSender:forEvent:]
6 UIKit -[UIApplication sendAction:to:from:forEvent:]
5 FourGameCenter 0x8d7fa
4 FourGameCenter 0x71830
3 FourGameCenter 0x797e6
2 libobjc.A.dylib _objc_rootAllocWithZone
1 libobjc.A.dylib class_createInstance
0 libsystem_c.dylib calloc
You can't do the following in clearImages:
[self setImageArray:nil];
[imageArray removeAllObjects];
In the snippet above, you've just set imageArray to nil. You can't then send the nil object a removeAllObjects message: it'll just silently do nothing.
You need to reorder your lines to:
[imageArray removeAllObjects];
[self setImageArray:nil];
[self setImageArray:nil]
will remove the image objects automatically, so no need to do the removeObjects.
However if you are using those images in UIImageViews elsewhere, and those UIImageViews are retained or used in a view elsewhere, you will need to release those/remove the UIImageView from the superview as well.
[imageView removeFromSuperview];
Or if you have the UIImageViews in an array:
[imageViewArray makeObjectsPerformSelector:#selector(removeFromSuperview)];
You are mixing metaphors here - you use a property but set it like an ivar - its possible that creates a leak. Also, if you release the array, you don't have to release every object as it will do that for you.
So, use an ivar
#MyClass...
{
NSMutableArray *imageArray;
}
Now you can set it to new arrays, and for sure the old array is released. If you want to release the array completely, just set it to nil.
Alternately, if you want to use properties, then when you change the object, use:
self.imageArray = ...;
Now, a second problem - your code accesses imageArray directly (no leading "_") - did you synthesize the ivar using the same name? This is probably not a good idea as it just confuses people when they read your code. If you just drop the #synthesize, you now get the ivar "for free" as the property name with a "_" prepended. You can directly access that ivar but anyone reading your code will know its attached to a property.
EDIT: You obviously are not releasing the objects you think you are. Your problem is quite similar to this one. What you need to do is as follows:
1) create a UIImage subclass, and add a log statement in the dealloc. Instead of creating UIImages, you are going to create MyImages (the subclass), which means you'll need your subclass .h file anywhere you want to use it (pr put it in the pch file while debugging). Do this first to see if the images get released. If not you know your problem.
2) Subclass NSArray (NOT NSMutableArray, not you don't really need mutable arrays in the code you show above). If there are reasons that you must use mutable arrays, then when you set the ivar, use [MyArray arrayWithArray:theMutableArray] first. Log the dealloc.
Now run your tests. Either the array, or the images, is not getting released. Once you know which, you can track down the retain issue.
There is an old saying, I'll butcher it, but it goes something like, when you try everything that can possible be the cause of a problem, and that doesn't fix it, then it has to be something that you assume is NOT the problem that is actually it.
Check to see if you have zombies turned on in the scheme:diagnostics. EVen though Zombies are unlikely under ARC, the project might still have this turned on, which makes checking for memory leaks look like everything is leaking.
Related
I'm having some weird issues with our app, it crashes when using some UIImage.
I get the image with [UIImage imageNamed:#"imageName"] from the image asset.
But on some device it returns nil which crash my app, but It should not be nil.
I've already checked and its running on the main thread, there is enough memory left (although it was running low).
The image is PDF as single vector image in the image assets, this should create the correct sizes of the images.
Can any one give me any pointers on how to resolve this issue?
Thread : Crashed: com.apple.main-thread
0 CoreFoundation 0x1844d7108 CFDataGetBytePtr + 36
1 Foundation 0x18545a848 bytesInEncoding + 204
2 CoreFoundation 0x1844e88d4 -[__NSCFString UTF8String] + 80
3 CoreUI 0x18d6827c0 -[CUIStructuredThemeStore _canGetRenditionWithKey:isFPO:lookForSubstitutions:] + 780
4 CoreUI 0x18d6a5614 -[CUICatalog _resolvedRenditionKeyFromThemeRef:withBaseKey:scaleFactor:deviceIdiom:deviceSubtype:sizeClassHorizontal:sizeClassVertical:memoryClass:graphicsClass:graphicsFallBackOrder:] + 1484
5 CoreUI 0x18d6a4784 -[CUICatalog namedLookupWithName:scaleFactor:deviceIdiom:deviceSubtype:sizeClassHorizontal:sizeClassVertical:] + 148
6 UIKit 0x18a3df338 __98-[_UIAssetManager imageNamed:scale:idiom:subtype:cachingOptions:sizeClassPair:attachCatalogImage:]_block_invoke + 424
7 UIKit 0x18a3df0d8 -[_UIAssetManager imageNamed:scale:idiom:subtype:cachingOptions:sizeClassPair:attachCatalogImage:] + 212
8 UIKit 0x18a4f1698 -[UIImageAsset imageWithTraitCollection:] + 404
9 UIKit 0x18a3df7c0 -[_UIAssetManager imageNamed:withTrait:] + 276
10 UIKit 0x189e7277c +[UIImage imageNamed:inBundle:compatibleWithTraitCollection:] + 220
11 UIKit 0x189ccb47c +[UIImage imageNamed:] + 124
12 Speakap 0x1000bef50 -[LoadingView commonInit] (LoadingView.m:74)
13 Speakap 0x1000beabc -[LoadingView initWithFrame:] (LoadingView.m:28)
14 Speakap 0x1001348dc -[BaseTableViewController viewDidLoad] (BaseTableViewController.m:32)
15 Speakap 0x1001570d4 -[BaseMessageViewController viewDidLoad] (BaseMessageViewController.m:66)
16 Speakap 0x10014aa34 -[MessageViewController viewDidLoad] (MessageViewController.m:37)
17 UIKit 0x189b8c098 -[UIViewController loadViewIfRequired] + 996
18 UIKit 0x189ba4350 -[UIViewController __viewWillAppear:] + 132
19 UIKit 0x189d3dfb4 -[UINavigationController _startCustomTransition:] + 1052
20 UIKit 0x189c4a190 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
21 UIKit 0x189c49e6c -[UINavigationController __viewWillLayoutSubviews] + 60
22 UIKit 0x189c49dd4 -[UILayoutContainerView layoutSubviews] + 208
23 UIKit 0x189b877ac -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 644
24 QuartzCore 0x189386b58 -[CALayer layoutSublayers] + 148
25 QuartzCore 0x189381764 CA::Layer::layout_if_needed(CA::Transaction*) + 292
26 QuartzCore 0x189381624 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
27 QuartzCore 0x189380cc0 CA::Context::commit_transaction(CA::Transaction*) + 252
28 QuartzCore 0x189380a08 CA::Transaction::commit() + 512
29 UIKit 0x189b7d9d8 _afterCACommitHandler + 180
30 CoreFoundation 0x1845afbd0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
31 CoreFoundation 0x1845ad974 __CFRunLoopDoObservers + 372
32 CoreFoundation 0x1845adda4 __CFRunLoopRun + 928
33 CoreFoundation 0x1844dcca0 CFRunLoopRunSpecific + 384
34 GraphicsServices 0x18f718088 GSEventRunModal + 180
35 UIKit 0x189bf4ffc UIApplicationMain + 204
36 Speakap 0x100162b24 main (main.m:14)
37 libdyld.dylib 0x19990a8b8 start + 4
I've experienced some "trouble" in memory management using [UIImage imageNamed:#""] within low memory context.
As the documentation says:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/clm/UIImage/imageNamed:
Discussion
This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method locates and loads the image data from disk or asset catalog, and then returns the resulting object. In iOS 9 and later, this method is thread safe.
I don't know on which OS the crash happens, but it can be an idea.
Other point, does it still happens if your replace imageNamed: by imageWithContentOfFile: or initWithContentOfFile: ?
The memory management is different (no system cache):
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/initWithContentsOfFile:
Discussion
This method loads the image data into memory and marks it as purgeable. If the data is purged and needs to be reloaded, the image object loads that data again from the specified path.
https://github.com/rickytan/RTImageAssets
install above plugin to xcode and go to file -> imageAssets ->Generate Missing assets.i will generate all missing images.
The only possibility I can see here, is that a specific device might not have the proper file. For example, if the device has Retina display and there is no #2x image in the image asset then it will be returned as nil etc.
My suggestion is to make sure all required sizes are actually exist inside the image asset + make sure to use asset group name for the imageNamed: parameter.
Also, are you testing it over various simulators or real devices?
It may possible that you are using hight resolution image & check on iPhone 4/4s or vise-a-versa.
Add all the sizes of images in image assets & then check for the image, whether it returns nil or not.
No need to mention #2x,#3x if we are using image assets,it will automatically take appropriate size from image assets.
We created custom font for our application with custom Emoji symbols. Sometimes app crashes with following stacktrace (always the same):
0 libsystem_platform.dylib 0x38b8d486 _platform_memmove$VARIANT$Swift + 102
1 CoreFoundation 0x2d8f7575 CFDataGetBytes + 237
2 ImageIO 0x2e6e1e8f CGImageReadGetBytesAtOffset + 299
3 ImageIO 0x2e6e1d59 CGImageReadSessionGetBytes + 29
4 ImageIO 0x2e825973 read_fn + 23
5 ImageIO 0x2e6e1cb1 png_read_sig + 45
6 ImageIO 0x2e6e1935 _cg_png_read_info + 33
7 ImageIO 0x2e6ea15b copyImageBlockSetPNG + 1123
8 ImageIO 0x2e6e9779 ImageProviderCopyImageBlockSetCallback + 529
9 CoreGraphics 0x2da2647d CGImageProviderCopyImageBlockSetWithOptions + 137
10 CoreGraphics 0x2da492f7 CGImageProviderCopyImageBlockSet + 39
11 CoreGraphics 0x2da2614f img_blocks_create + 411
12 CoreGraphics 0x2da492bb img_blocks_extent + 63
13 CoreGraphics 0x2da49271 img_interpolate_extent + 109
14 CoreGraphics 0x2da1a12d img_data_lock + 4421
15 CoreGraphics 0x2da187e9 CGSImageDataLock + 89
16 libRIP.A.dylib 0x2dd65da7 ripc_AcquireImage + 99
17 libRIP.A.dylib 0x2dd65131 ripc_DrawImage + 601
18 CoreGraphics 0x2da186fb CGContextDelegateDrawImage + 51
19 CoreGraphics 0x2da18581 CGContextDrawImage + 285
20 CoreText 0x2e0a43db TCGImageData::DrawInRect(CGRect) const + 311
21 CoreText 0x2e062299 CTFontDrawGlyphsWithAdvances + 705
22 CoreText 0x2e070d55 TRun::DrawGlyphs(CGContext*, CFRange) const + 241
23 CoreText 0x2e070c25 TLine::DrawGlyphs(CGContext*) const + 157
24 UIFoundation 0x358860df __NSStringDrawingEngine + 10151
25 UIFoundation 0x35883863 -[NSString(NSExtendedStringDrawing) drawWithRect:options:attributes:context:] + 151
26 UIKit 0x301e72c9 -[UILabel _drawTextInRect:baselineCalculationOnly:] + 4225
27 UIKit 0x3024d709 -[UILabel drawTextInRect:] + 501
28 UIKit 0x3024d50b -[UILabel drawRect:] + 79
29 UIKit 0x3024d4a9 -[UIView(CALayerDelegate) drawLayer:inContext:] + 373
30 QuartzCore 0x2fe79189 -[CALayer drawInContext:] + 101
I don't know is it possible to get help for such situation, but maybe someone from Apple could give advice what is wrong with font. I could provide font if needed.
Unfortunately this is not a conclusive answer, but it's too long for a comment so I guess feel free to downvote, those who do that sort of thing. But I hope you won't, because I think this could be useful information.
I took a pretty deep look into this font, which uses the newly-defined 'sbix' table, just as Apple's Color Emoji font does, to store color images (PNGs in this case) for icons. I went through the data table and dumped out each of the icons to PNG files and everything appeared to be okay (what it means is: the 'sbix' table itself seems to follow the specification, and the resulting PNG images do not appear to be corrupted and are in fact rather amusing!).
However: there are some characteristics of this font compared to the Apple Color Emoji font that I find a bit odd. Apple's font has 7 "strikes" (sizes): 20, 32, 40, 48, 64, 96, 160, whereas yours has only one: 285. My understanding is that the system is supposed to up/down-scale when asked for a font size that doesn't exist in the font (e.g. you call for 50, it scales 285 down to 50), but given that Apple's maximum strike size is 160 it makes me wonder whether there is some unspecified upper size limit for fonts. Another thing I noticed is that the PNG data is 256 pixels wide and I'm not sure how that's supposed to relate to the 285 size (maybe padding?).
Looking at the stack trace, it looks like it's getting the image data out of the font, but failing somewhere during the actual rendering of the image.
I'm not sure what you used to create this font, but something you might try if you can is to scale the images such that your strike size is 160, matching Apple's maximum, and see what happens there. Sorry I could not be of more help, but I hope this at least gives you something to investigate further.
I am getting some crash logs in Crashlytics for my iOS app and I am stumped as to how to interpret them. I have tried everything I can think of in my app to create a crash, and have been unable to create one that will result in a stack trace like the following:
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x397e6b26 objc_msgSend + 5
1 Foundation 0x2fcc7f8d -[NSError dealloc] + 60
2 libobjc.A.dylib 0x397f6b0b objc_object::sidetable_release(bool) + 174
3 Foundation 0x2fd241f5 -[NSFilesystemItemRemoveOperation dealloc] + 60
4 libobjc.A.dylib 0x397f6b0b objc_object::sidetable_release(bool) + 174
5 libobjc.A.dylib 0x397e8007 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
6 CoreFoundation 0x2f2de981 _CFAutoreleasePoolPop + 16
7 UIKit 0x31b1624d _wrapRunLoopWithAutoreleasePoolHandler + 36
8 CoreFoundation 0x2f3761cd __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
9 CoreFoundation 0x2f373b71 __CFRunLoopDoObservers + 284
10 CoreFoundation 0x2f373eb3 __CFRunLoopRun + 730
11 CoreFoundation 0x2f2dec27 CFRunLoopRunSpecific + 522
12 CoreFoundation 0x2f2dea0b CFRunLoopRunInMode + 106
13 GraphicsServices 0x34005283 GSEventRunModal + 138
14 UIKit 0x31b82049 UIApplicationMain + 1136
15 Pocket Linesman 0x000d5a8b main + 17 (main.m:17)
Would anyone know how I can go about interpreting the cause of this stack trace? It seems that something is occurring when I am deleting an object in my app from the file system, but I am not 100% sure.
We can see in the backtrace _CFAutoreleasePoolPop.
It means that the crash occurred while the autorelease pool of the current run loop was trying to release an object that was marked for autorelease...
Usually, it means that an autoreleased object was released manually.
Imagine the following:
{
NSObject * o;
o = [ [ [ NSObject alloc ] init ] autorelease ];
[ o release ];
}
The o object here has a retain count of 1, and is marked for autorelease, so the current instance of the autorelease pool will send it a release message next time it's drained.
So the manual call to release, which is wrong, won't produce a crash, as the object is still leaving yet. But the object will then be deallocated, leaving the autorelease pool with a reference to a deallocated object.
When the pool is drained, it will then try to send a release message to that invalid reference, and your app will crash.
By the internal NSFilesystemItemRemoveOperation being deallocated, I would guess that you're dealing with problematic memory management around NSFileManager's removeItemAtPath:error:. Are you making this call anywhere in your code?
I'm experiencing a crash on my iPad which I think is related to my app just running out of memory, however I can't seem to glean any information about the crash itself in order to resolve it. The app uses ARC.
The app spends about 20 minutes downloading data from our server and populating a Core Data model. Around the 20 minutes mark, the app crashes.
The device isn't running out of space - in fact the downloaded content takes up just a hundred megabytes. I'm using only a single managed context object (nb. I'm not saving the context until the entire data set has downloaded).
When I run in debug with an exception breakpoint enabled, I app just crashes without breaking and without displaying any type of warning or error.
Any advice on how to track down the problem? From the crash log below, does it look like the app is just running out of memory, or might it be
Here's the crash log:
Incident Identifier: A619465F-2E85-4BBC-BBE7-2330D4700FB8
CrashReporter Key: 6fa0c5a4f6cbeaf7a98e6c0e9ad8be6b27789039
Hardware Model: iPad2,2
OS Version: iPhone OS 6.0.1 (10A523)
Kernel Version: Darwin Kernel Version 13.0.0: Wed Oct 10 23:29:31 PDT 2012; root:xnu-2107.2.34~2/RELEASE_ARM_S5L8940X
Date: 2013-04-27 09:53:43 +0200
Time since snapshot: 152 ms
Free pages: 934
Active pages: 3455
Inactive pages: 1821
Throttled pages: 103117
Purgeable pages: 0
Wired pages: 18795
Largest process: GreaseBook
Processes
Name <UUID> rpages recent_max [reason] (state)
MobileMail <27df582d2bed3501834661269810ad98> 3928 3928 [vm] (continuous)
kbd <24d58ac14ed3340380492fef46eac29d> 574 574 [vm] (daemon)
tccd <eb5ddcf533663f8d987d67cae6a4c4ea> 281 281 [vm] (daemon)
GreaseBook <2f5df68a7078386298eadbb24ebbdb33> 84210 84210 [vm] (frontmost) (resume)
ptpd <0cac6936ffeb362d98eb8073af935d21> 992 992 (daemon)
mediaserverd <bdc35c073fe134b9a39b96342a80159e> 1082 1082 (daemon)
syslogd <cbef142fa0a839f0885afb693fb169c3> 281 281 (daemon)
locationd <4bee615548dd33f48e18bfed4296f05d> 1675 1675 (daemon)
wifid <a243b2fcde2537159660b3ee7e809df4> 649 649 (daemon)
aosnotifyd <01901b13681f3582b5bfbe53504d08d6> 480 480 (daemon)
dataaccessd <117e4e475b14305982f52484564cfbc7> 1319 1319 (daemon)
iaptransportd <f784f30dc09d32078d87b450e8113ef6> 241 241 (daemon)
SpringBoard <0e3571e8067533e2811a6d444f10a349> 4058 4058
backboardd <a9b5346126a939dfb0920a4bbc48201b> 6057 6057 (daemon)
imagent <d15f873abdd233f0a34d77a7d36e9e0f> 329 329 (daemon)
mDNSResponder <3e557693f3073697a58da6d27a827d97> 283 283 (daemon)
UserEventAgent <6edfd8d8dba23187b05772dcdfc94f90> 589 589 (daemon)
syslog_relay <45e9844605d737a08368b5215bb54426> 0 0 (daemon)
CVMServer <3ec015e0150d341a929ebbbc45f4c8ac> 104 104 (daemon)
afcd <b0aff2e7952e34a9882fec81a8dcdbb2> 165 165 (daemon)
notification_pro <845b7beebc8538ca9ceef731031983b7> 203 203 (daemon)
filecoordination <fbab576f37a63b56a1039153fc1aa7d8> 195 195 (daemon)
distnoted <a89af76ec8633ac2bbe99bc2b7964bb0> 132 132 (daemon)
apsd <d0e432fd45023d629ffb305b7e79d7fb> 403 403 (daemon)
aggregated <cd70154f955c31bbab58bf5f0acd3acd> 108 108 (daemon)
networkd <b24547cbe04b3e94a4bd406e586cdf8a> 222 222 (daemon)
BTServer <f57113a7cc2c33678ee832bc088276be> 356 356 (daemon)
configd <4245d73a9e96360399452cf6b8671844> 576 576 (daemon)
fairplayd.K94 <1a5f575df8f4368db1eae7ba3da11150> 270 270 (daemon)
fseventsd <996cc4ca03793184aea8d781b55bce08> 362 362 (daemon)
powerd <2d2ffed5e69638aeba1b92ef124ed861> 198 198 (daemon)
securityd <c35e701a5aab3968ae8d93ef8db02e07> 159 159 (daemon)
lockdownd <481275a4062931708a7440ff0f73f229> 495 495 (daemon)
CommCenterClassi <c10fa2a1b7673e1ab14e6ecd11b9b7e7> 557 557 (daemon)
notifyd <51c0e03da8a93ac8a595442fcaac531f> 199 199 (daemon)
**End**
When downloading large data sets into core data, you need to account for lots of things. When it comes to memory management, the more popular issues are described below.
First and foremost, you need to save frequently, which allows you to purge the memory from the NSManagedObjectContext (aka MOC). At any time, you can see what objects the MOC has, by looking at the registeredObjects property of the MOC.
Normally, when you save a MOC, any objects that do not have a strong reference to them are removed from the MOC. Again, you can check after saving by looking at the registeredObjects. However, if you have relationships in your model, then the objects will contain strong references to each other, which creates a retain cycle. Thus, the objects will never be released until the retain cycle is broken.
You break retain cycles in a MOC by using refreshObject:object mergeChanges:NO. You can blow away all objects by calling reset but that is rather draconian, and you need to make sure you do not hold any references to managed objects when you do that.
Even if you don't have retain cycles between your managed objects, you could still be inadvertently retaining objects that you will never use again. This is where, even though you are using ARC, you still need to understand some memory management rules. Specifically, auto released objects. They will get automatically released, but not until the autorelease pool reclaims objects.
Thus, you should wrap your operations in your own autorelease pool. This is very simple:
#autoreleasepool {
// Unless you hold references elsewhere, objects allocated in here will be
// auto released when this scope ends.
}
If you have a thread doing your downloading, and you use a MOC of NSPrivateQueueConcurrencyType, the block you pass to performBlock gets automatically wrapped in an autorelease pool.
I have an older app that I converted to use ARC. The original version did not have memory leaks, and I fixed all of the errors after the conversion using the memory diagnostics in the debugger. Occasionally, the app will crash and the stack trace looks like ARC is stuck in either an infinite retain or release cycle, like this:
0 CoreFoundation 0x329046a6 CFRelease + 46
1 CoreFoundation 0x329046da CFRelease + 98
2 CoreFoundation 0x329046da CFRelease + 98
3 CoreFoundation 0x329046da CFRelease + 98
4 CoreFoundation 0x329046da CFRelease + 98
Unfortunately, the stack traces cut off at 512 entries, so I can't see where this chain started. Apple said this could happen if the alloc and init methods are separated and the init method returns a different object than alloc. I checked all of our allocations and they follow the recommended format:
Class *var = [[Class alloc] initMethod:arg];
Has anyone seen an infinite loop of this sort? I have not been able to catch it while using the Xcode debugger, and it is very inconsistent. Since ARC is injecting the retains and releases, I don't have any idea where the crash originates.