Recently I have finished my first Iphone app and it works grate.... except for when i did a intense session using instruments to find leaks after awhile with no leaks, all of a sudden get about 1.3Kb worth. In the stack trace they all point to the exact line that I release a UIViewControler on after pushing it to the Navigation controller (Ill post this code a bit further down). The Leak seem to happen after a few time navagating through the ViewControlers and back again. I know this is a very generally question but I hope someone could point me in the right direction. I have spent a few days trying to solve this and it is starting to dive me crazy!
My app is a Navigation based one, here is how it works in a nutshell:
Starts with a UIViewControler which when a button is pressed goes to another UIViewControler containing a TableView.
From here depending on the contents of the array that populates the TableView it could go to a UIViewControler containing a PickerView then to the last UIViewControler or just go straight to the last UIViewControler bypassing the one with the PickerView.
Here is the code that the stack trace says the Leak is on:
SoundConfiger *third = [[SoundConfiger alloc] initWithNibName:#"SoundConfiger" bundle:[NSBundle mainBundle]];
[third setTitle:#"Sound Link"];
third.myData = myData;
third.selectedRow = row;
third.currentChoise = nil;
[self.navigationController pushViewController:third animated:YES];
[third release]; <---- Instruments says the leak is here on this line.
Shouldn't the NavigationController be responsible for this UIViewcontroler now? I have not called retain on third anywhere else and it only exists in this function.
I have a Bunch of Leaks from UIkit and QuartsZone. I have a screen shot bellow of some of them, in the stack traces all point to the same snippet of code, in the same function, in the same object as stated above at some point in the trace:
Here is a Link to the image as I can't post images yet: Link no longer valid
Here is the compleat stack trace from the first GeneralBlock-16 in the list. The one in bold (line 29) is the code snippet above:
0 libSystem.B.dylib malloc
1 CoreFoundation -[__NSArrayM insertObject:atIndex:]
2 CoreFoundation -[__NSArrayM addObject:]
3 UIKit -[UIView(UIViewGestures) addGestureRecognizer:]
4 UIKit -[UISwitch _commonInit]
5 UIKit -[UISwitch initWithCoder:]
6 UIKit UINibDecoderDecodeObjectForValue
7 UIKit UINibDecoderDecodeObjectForValue
8 UIKit -[UINibDecoder decodeObjectForKey:]
9 UIKit -[UIView initWithCoder:]
10 UIKit UINibDecoderDecodeObjectForValue
11 UIKit -[UINibDecoder decodeObjectForKey:]
12 UIKit -[UIRuntimeConnection initWithCoder:]
13 UIKit UINibDecoderDecodeObjectForValue
14 UIKit UINibDecoderDecodeObjectForValue
15 UIKit -[UINibDecoder decodeObjectForKey:]
16 UIKit -[UINib instantiateWithOwner:options:]
17 UIKit -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:]
18 UIKit -[UIViewController _loadViewFromNibNamed:bundle:]
19 UIKit -[UIViewController loadView]
20 UIKit -[UIViewController view]
21 UIKit -[UIViewController contentScrollView]
22 UIKit -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:]
23 UIKit -[UINavigationController _layoutViewController:]
24 UIKit -[UINavigationController _startTransition:fromViewController:toViewController:]
25 UIKit -[UINavigationController _startDeferredTransitionIfNeeded]
26 UIKit -[UINavigationController pushViewController:transition:forceImmediate:]
27 UIKit 0x6ea9b5
28 UIKit -[UINavigationController pushViewController:animated:]
29 Booby Trap -[SelectEventTypeviewcontroler ChooseThisOne] /Users/chriswyllie/Documents/Booby Trap/Booby Trap/Classes/SelectEventTypeviewcontroler.m:91
30 CoreFoundation -[NSObject(NSObject) performSelector:withObject:withObject:]
31 UIKit -[UIApplication sendAction:to:from:forEvent:]
32 UIKit -[UIApplication sendAction:toTarget:fromSender:forEvent:]
33 UIKit -[UIControl sendAction:to:forEvent:]
34 UIKit -[UIControl(Internal) _sendActionsForEvents:withEvent:]
35 UIKit -[UIControl touchesEnded:withEvent:]
36 UIKit -[UIWindow _sendTouchesForEvent:]
37 UIKit -[UIWindow sendEvent:]
38 UIKit -[UIApplication sendEvent:]
39 UIKit _UIApplicationHandleEvent
40 GraphicsServices PurpleEventCallback
41 CoreFoundation CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION
42 CoreFoundation __CFRunLoopDoSource1
43 CoreFoundation __CFRunLoopRun
44 CoreFoundation CFRunLoopRunSpecific
45 CoreFoundation CFRunLoopRunInMode
46 GraphicsServices GSEventRunModal
47 GraphicsServices GSEventRun
48 UIKit -[UIApplication _run]
49 UIKit UIApplicationMain
50 Booby Trap main /Users/chriswyllie/Documents/Booby Trap/Booby Trap/main.m:14
51 Booby Trap start
Thanks for your help in advance, I am hope I am just doing something silly and I need a fresh set of eyes to see it. Let me know If you need more info.
Well I am a Tool :)
I was not handeling the IBOutlets correctly in each viewControler.
I was not declaring each IBOutlet using #property with a retain, using "self.someLabel = nil" (to release and set to the IBOutlets to nil) in the viewDidUnload method for a memory warning and then finally releasing in in dealloc.
thus tool. lol
What I was doing was declaring was "IBOutlet UILabel *someLabel;" in the header with no #property and this was causing the leaks seen above, they don't happen right away it takes a while and when they do the stack trace and every thing dose not help to much.
They only way I found what was leaking was striping everything out of my app and I mean everything until the leak went away.
Thanks for your help Ishu Gupta, I am glad we had a outcome.
Here are the relevant link to show how to do IBOutlets correctly: What happens if I don't retain IBOutlet?
SoundConfiger *third = [[[SoundConfiger alloc] initWithNibName:#"SoundConfiger" bundle:[NSBundle mainBundle]] autorelease];
and remove
[third release]; this line.
You can fix only those leaks which comes because of your code(forget release any object or some wrong things). But some time you get extra leaks these are present in iphone sdk. Actully some of functions or properties of iPhone having leaks.so these can be fixed only when you change the use of these.
And one thing more 1.3 KB leak is not bad if it will not be increase with app operations.
Related
I am creating my first iPhone app in which the first screen displays a table view the user selects from. It works before localization using the method below.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
navigationController = [[UINavigationController alloc] init];
[self.window addSubview:[self.navigationController view]];
if(self.selectCategoryViewController == nil)
{
SelectCategoryViewController *viewTwo = [[SelectCategoryViewController alloc] initWithNibName:#"SelectCategoryViewController" bundle:[NSBundle mainBundle]];
self.selectCategoryViewController = viewTwo;
[viewTwo release];
}
[self.navigationController setNavigationBarHidden:YES];//this will hide the navigation bar
[self.navigationController pushViewController:self.selectCategoryViewController animated:YES];
//self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
After I localized it by adding the Japanese localization file and changing the above to this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
navigationController = [[UINavigationController alloc] init];
[self.window addSubview:[self.navigationController view]];
if(self.selectCategoryViewController == nil)
{
NSBundle *myLocalizedBundle=[NSBundle bundleWithPath:[NSString stringWithFormat:[[NSBundle mainBundle]bundlePath],"en.lproj"]];
NSLog(#"the localized bundle is %#",myLocalizedBundle);
SelectCategoryViewController *viewTwo=[[SelectCategoryViewController alloc] initWithNibName:#"SelectCategoryViewController" bundle:myLocalizedBundle];
self.selectCategoryViewController = viewTwo;
[viewTwo release];
}
[self.navigationController setNavigationBarHidden:YES];//this will hide the navigation bar
[self.navigationController pushViewController:self.selectCategoryViewController animated:YES];
[self.window makeKeyAndVisible];
return YES;
}
it crashes with the following error:
√sh.app> (loaded)
2013-02-18 18:04:35.196 PictureEnglish[5529:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFString substringFromIndex:]: Range or index out of bounds'
*** Call stack at first throw:
(
0 CoreFoundation 0x012775a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x013cb313 objc_exception_throw + 44
2 CoreFoundation 0x0122fef8 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x0122fe6a +[NSException raise:format:] + 58
4 Foundation 0x00033086 -[NSString substringFromIndex:] + 133
5 PictureEnglish 0x00008524 -[SelectCategoryViewController viewDidLoad] + 937
6 UIKit 0x00378089 -[UIViewController view] + 179
7 UIKit 0x00376482 -[UIViewController contentScrollView] + 42
8 UIKit 0x00386f25 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
9 UIKit 0x00385555 -[UINavigationController _layoutViewController:] + 43
10 UIKit 0x00386870 -[UINavigationController _startTransition:fromViewController:toViewController:] + 524
11 UIKit 0x0038132a -[UINavigationController _startDeferredTransitionIfNeeded] + 266
12 UIKit 0x0049c2e9 -[UILayoutContainerView layoutSubviews] + 226
13 QuartzCore 0x010a7a5a -[CALayer layoutSublayers] + 181
14 QuartzCore 0x010a9ddc CALayerLayoutIfNeeded + 220
15 QuartzCore 0x0104f0b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
16 QuartzCore 0x01050294 _ZN2CA11Transaction6commitEv + 292
17 UIKit 0x002ca9c9 -[UIApplication _reportAppLaunchFinished] + 39
18 UIKit 0x002cae83 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 690
19 UIKit 0x002d5617 -[UIApplication handleEvent:withNewEvent:] + 1533
20 UIKit 0x002cdabf -[UIApplication sendEvent:] + 71
21 UIKit 0x002d2f2e _UIApplicationHandleEvent + 7576
22 GraphicsServices 0x01bcf992 PurpleEventCallback + 1550
23 CoreFoundation 0x01258944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
24 CoreFoundation 0x011b8cf7 __CFRunLoopDoSource1 + 215
25 CoreFoundation 0x011b5f83 __CFRunLoopRun + 979
26 CoreFoundation 0x011b5840 CFRunLoopRunSpecific + 208
27 CoreFoundation 0x011b5761 CFRunLoopRunInMode + 97
28 UIKit 0x002ca7d2 -[UIApplication _run] + 623
29 UIKit 0x002d6c93 UIApplicationMain + 1160
30 PictureEnglish 0x00001cec main + 102
31 PictureEnglish 0x00001c7d start + 53
32 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Any suggestions on how I should call the SelectCategoryViewController for the selected language?
This line looks wrong to me:
NSBundle *myLocalizedBundle=[NSBundle bundleWithPath:[NSString stringWithFormat:[[NSBundle mainBundle]bundlePath],"en.lproj"]];
You probably meant something like this:
NSString* path= [[NSBundle mainBundle] pathForResource:#"en" ofType:#"lproj"];
NSBundle* bundle:myLocalizedBundle = [NSBundle bundleWithPath:path];
SelectCategoryViewController *viewTwo = [[SelectCategoryViewController alloc] initWithNibName:#"SelectCategoryViewController" bundle:myLocalizedBundle];
This is discussed more here: Manually loading a different localized nib in iOs
Note that this is only required if you want to do an in-app language selection. Localization should typically use the iOS device's selected language, in which case all this is much more straightforward (you simply let iOS pick the bundle for you).
xcode 5:
i had to clean build, clean build folder,delete derived data, reset simulator, close simulator, close Xcode.
Open project again and it's working.
Problem - This is a problem of project path, I think [self.window makeWindowKeyVisible] can not be able to find a path to your first assigned controller...
Solution - It happens some time, when your project suddenly stopped work, So no worries - just shift your project to other path, or just change the name of folder where actually your project resides and it will started working fine....
It works for me successfully...
I have a TTSplitViewController in which I am trying to show a UITabBarController at the left pane, via the code:
#implementation SplitAppController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
[self setupURLRouting];
}
return self;
}
- (void)setupURLRouting {
[self routePrimaryNavigator];
[self routeDetailsNavigator];
}
- (void)routePrimaryNavigator {
TTURLMap* map = self.primaryNavigator.URLMap;
// Forward all unhandled URL actions to the right navigator.
[map from: #"*" toObject: self selector: #selector(willOpenUrlPath:)];
[map from:#"tt://primary" toViewController:[RootViewController class]];
}
RootViewController here is a UITabBarController. However, I am getting the following error:
2011-07-08 08:04:23.739 app[3241:207] -[RootViewController topViewController]: unrecognized selector sent to instance 0x520c060
2011-07-08 08:04:23.755 app[3241:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RootViewController topViewController]: unrecognized selector sent to instance 0x520c060'
*** Call stack at first throw:
(
0 CoreFoundation 0x017d95a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0192d313 objc_exception_throw + 44
2 CoreFoundation 0x017db0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0174a966 ___forwarding___ + 966
4 CoreFoundation 0x0174a522 _CF_forwarding_prep_0 + 50
5 app 0x000f73ff -[TTSplitViewController updateSplitViewButton] + 176
6 app 0x000f75d9 -[TTSplitViewController viewDidAppear:] + 90
7 UIKit 0x00ae1fab -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] + 694
8 UIKit 0x00a64e4b -[UIView(Internal) _didMoveFromWindow:toWindow:] + 918
9 UIKit 0x00a63a60 -[UIView(Hierarchy) _postMovedFromSuperview:] + 166
10 UIKit 0x00a5c750 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1080
11 UIKit 0x00a5aaa3 -[UIView(Hierarchy) addSubview:] + 57
12 app 0x00083d01 -[TTBaseNavigator setRootViewController:] + 306
13 app 0x000841f9 -[TTBaseNavigator presentController:parentController:mode:action:] + 70
14 app 0x00084437 -[TTBaseNavigator presentController:parentURLPath:withPattern:action:] + 359
15 app 0x00084975 -[TTBaseNavigator openURLAction:] + 1320
16 app 0x0000c440 -[appAppDelegate application:didFinishLaunchingWithOptions:] + 848
17 UIKit 0x00a2bc89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
18 UIKit 0x00a2dd88 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
19 UIKit 0x00a38617 -[UIApplication handleEvent:withNewEvent:] + 1533
20 UIKit 0x00a30abf -[UIApplication sendEvent:] + 71
21 UIKit 0x00a35f2e _UIApplicationHandleEvent + 7576
22 GraphicsServices 0x01fee992 PurpleEventCallback + 1550
23 CoreFoundation 0x017ba944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
24 CoreFoundation 0x0171acf7 __CFRunLoopDoSource1 + 215
25 CoreFoundation 0x01717f83 __CFRunLoopRun + 979
26 CoreFoundation 0x01717840 CFRunLoopRunSpecific + 208
27 CoreFoundation 0x01717761 CFRunLoopRunInMode + 97
28 UIKit 0x00a2d7d2 -[UIApplication _run] + 623
29 UIKit 0x00a39c93 UIApplicationMain + 1160
30 app 0x00031342 main + 130
31 app 0x00002a75 start + 53
)
terminate called after throwing an instance of 'NSException'
How do I fix this?
Seems like your code is expecting RootViewController to be a subclass of UINavigationController.
If you didn't write that code, you can make a UINavigationController subclass, and initialize it with your tab bar controller as a root view controller, and hide the navigation bar, I think this would give the results you are looking for.
EmilioPelaez is quite right, I just succeeded with a similar solution like this, and it works!
#implementation MainViewController
- (id)initWithNavigatorURL:(NSURL *)URL query:(NSDictionary *)query {
MainTabBarController *mainTabBarController = [[MainTabBarController alloc] init];
[mainTabBarController setTabURLs:[NSArray arrayWithObjects:
#"tt://firstLink",
#"tt://secondLink",
nil]];
self = [super initWithRootViewController:mainTabBarController];
[mainTabBarController release];
self.navigationBarHidden = YES;
return self;
}
#end
I found another way to make it work (and maybe the better way that reduce code complexity):
inherit UITabBarController with this additional method:
- (UIViewController *)topViewController {
return self;
}
It works perfectly.
is this right
[map from:#"tt://primary" toViewController:[RootViewController class]];
my suggestion is
[map from:#"tt://primary" toViewController:RootViewControllerobject];
IBOutlet UITextView *readme;
[super viewDidLoad];
NSString *string = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"README" ofType:#"txt"] encoding:NSUTF8StringEncoding error:nil];
readme.text = string;
This part of code makes EXC_BAD_ACCESS in UIApplicationMain when i change tab item to other. without this code everything working fine.
Any ideas?
NSZombieEnabled = YES, but point is leave on same position while i press next step.
IBOutlet is connected as reference outlet to readme. This is a stack.
0 libSystem.B.dylib calloc 1 libobjc.A.dylib NXHashInsert 2 libobjc.A.dylib
_NXHashRehashToCapacity 3 libobjc.A.dylib NXHashInsert 4 libobjc.A.dylib realizeClass(class_t*) 5 libobjc.A.dylib
_class_getNonMetaClass 6 libobjc.A.dylib _class_initialize 7 libobjc.A.dylib prepareForMethodLookup 8 libobjc.A.dylib lookUpMethod 9 libobjc.A.dylib
_class_lookupMethodAndLoadCache 10 libobjc.A.dylib objc_msgSend 11 UIKit -[UIWebDocumentView initSimpleHTMLDocumentWithStyle:editable:withFrame:withPreferences:] 12 UIKit -[UITextView commonInitWithWebDocumentView:isDecoding:] 13 UIKit -[UITextView initWithCoder:] 14 Foundation
_decodeObjectBinary 15 Foundation -[NSKeyedUnarchiver
_decodeArrayOfObjectsForKey:] 16 Foundation -[NSArray(NSArray) initWithCoder:] 17 Foundation
_decodeObjectBinary 18 Foundation _decodeObject 19 UIKit -[UIView initWithCoder:] 20 Foundation
_decodeObjectBinary 21 Foundation _decodeObject 22 UIKit -[UIRuntimeConnection initWithCoder:] 23 Foundation
_decodeObjectBinary 24 Foundation -[NSKeyedUnarchiver
_decodeArrayOfObjectsForKey:] 25 Foundation -[NSArray(NSArray) initWithCoder:] 26 Foundation
_decodeObjectBinary 27 Foundation _decodeObject 28 UIKit -[UINib instantiateWithOwner:options:] 29 UIKit
-[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] 30 UIKit -[UIViewController
_loadViewFromNibNamed:bundle:] 31 UIKit -[UIViewController loadView] 32 UIKit -[UIViewController view] 33 UIKit -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] 34 UIKit -[UITabBarController transitionFromViewController:toViewController:] 35 UIKit -[UITabBarController
_setSelectedViewController:] 36 UIKit -[UITabBarController
_tabBarItemClicked:] 37 UIKit -[UIApplication sendAction:to:from:forEvent:] 38 UIKit -[UITabBar
_sendAction:withEvent:] 39 UIKit -[UIApplication sendAction:to:from:forEvent:] 40 UIKit -[UIControl sendAction:to:forEvent:] 41 UIKit
-[UIControl(Internal) _sendActionsForEvents:withEvent:] 42 UIKit -[UIControl sendActionsForControlEvents:] 43 UIKit -[UIApplication sendAction:to:from:forEvent:] 44 UIKit -[UIControl sendAction:to:forEvent:] 45 UIKit
-[UIControl(Internal) _sendActionsForEvents:withEvent:] 46 UIKit -[UIControl touchesEnded:withEvent:] 47 UIKit
-[UIWindow _sendTouchesForEvent:] 48 UIKit -[UIApplication sendEvent:] 49 UIKit _UIApplicationHandleEvent 50 GraphicsServices PurpleEventCallback 51 CoreFoundation
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ 52 CoreFoundation
__CFRunLoopDoSource1 53 CoreFoundation __CFRunLoopRun 54 CoreFoundation CFRunLoopRunSpecific 55 CoreFoundation CFRunLoopRunInMode 56 GraphicsServices GSEventRunModal 57 GraphicsServices GSEventRun 58 UIKit UIApplicationMain 59 snow iphone main /Users/mac/Documents/Programming/Projects/snow
- head/snow iphone/main.m:13 60 snow iphone start
SOLUTION
UIImage *imageForEvents = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"events" ofType:#"png"]];
UITabBarItem *eventsBar = [[UITabBarItem alloc] initWithTitle:#"Events" image:imageForEvents tag:0];
events.tabBarItem = eventsBar;
[eventsBar release];
this peace of code was create in table view controller area. after i was change it to appdelegate, error was go out.
strange that debug don't show appropriate line of code.
Set NSZombieEnabled to check which object is responsible for EXC_BAD_ACCESS.
Are you sure readme IBOutlet is exactly connected in Interface Builder?
NSLog(#"className of readme is \"%#\".", [readme className]);
BTW, UITextView text property has copy attribute, autoreleased string would be nice.
NSString *string = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"README" ofType:#"txt"] encoding:NSUTF8StringEncoding error:nil];
The code you have posted should not cause EXC_BAD_ACCESS. Since EXC_BAD_ACCESS is what happens when you try to send a message to a class that has deallocated, I would look in your app for where you either release something and do not set the pointer to nil or if you should be retaining something and are not doing so.
I have a memory leak while using NSFetchedResultsController objectAtIndex:
The stack frame is as follow:
0 CoreFoundation __CFDataAllocate
1 CoreFoundation __CFDataInit
2 CoreData -[NSSQLCore _prepareResultsFromResultSet:usingFetchPlan:withMatchingRows:]
3 CoreData -[NSSQLCore _newRowsForFetchPlan:selectedBy:withArgument:]
4 CoreData -[NSSQLCore newRowsForFetchPlan:]
5 CoreData -[NSSQLCore objectsForFetchRequest:inContext:]
6 CoreData -[NSSQLCore executeRequest:withContext:error:]
7 CoreData -[NSPersistentStoreCoordinator executeRequest:withContext:error:]
8 CoreData -[NSManagedObjectContext executeFetchRequest:error:]
9 CoreData _faultBatchAtIndex
10 CoreData -[_PFBatchFaultingArray objectAtIndex:]
---> 11 MyApp -[DocumentViewController tableView:heightForRowAtIndexPath:]
12 UIKit -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
13 UIKit -[UITableViewRowData rectForFooterInSection:]
14 UIKit -[UITableViewRowData heightForTable]
15 UIKit -[UITableView(_UITableViewPrivate) _updateContentSize]
16 UIKit -[UITableView noteNumberOfRowsChanged]
17 UIKit -[UITableView reloadData]
18 UIKit -[UITableView layoutSubviews]
19 QuartzCore -[CALayer layoutSublayers]
20 QuartzCore CALayerLayoutIfNeeded
21 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
22 QuartzCore CA::Transaction::commit()
23 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
24 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
25 CoreFoundation __CFRunLoopDoObservers
26 CoreFoundation __CFRunLoopRun
27 CoreFoundation CFRunLoopRunSpecific
28 CoreFoundation CFRunLoopRunInMode
29 GraphicsServices GSEventRunModal
30 GraphicsServices GSEventRun
31 UIKit UIApplicationMain
From this stack frame, it looks like the object accessed with objectAtIndex get leaked.
However, when I leave the controller, its dealloc method get called. In this method, all the objects fetched by the fetchedresultscontroller are turned into fault since I use [NSManagedObjectContext refreshObject:mergeChange].
To be complete in my description, below is the code where the leaking object is created:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
Page* page = [[self fetchedResultsController] objectAtIndexPath:indexPath];
UIImage* thumbnail = [page getThumbnail];
[[self managedObjectContext] refreshObject:page.image mergeChanges:NO];
CGFloat height = [PageCell cellImageSize:thumbnail].height + 20;
return height;
}
Any hint would be appreciated,
Thanks!
Check the code where you get the UIImage. The leak is most likely there. Where it is exactly depends on how you create the image object.
Barring more evidence, that looks more like a leak in the bowels of Core Data. File a bug.
I'm trying to kill all memory leaks in my iPhone 3.0 application. CLANG builds with all lights green so now I'm analyzing with Instruments.
This is easier said then done, since it is indicating hundreds of 16 byte leaks after just a few minutes of using the app. It seams to be mainly in UIKit, and the common part is that the end of the stack trace always calls [NSObject respondsToSelector]
Is this something I can ignore or what can be the reason for all these leaks?
I I can ignore them, is there a way to filter them out in Instruments, so I can detect the real leaks?
*EDIT
I managed to find the part of my code that caused the problem, but I still don't understand why.
I have a custom UIView with some text and a spinner that is visible during an async http request. When the request is done I call this method on the view:
- (void)fadeOut{
spinner.hidden = YES;
loadingLabel.hidden = YES;
messageLabel.hidden = YES;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeComplete)];
[UIView setAnimationDuration:0.40];
self.alpha = 0.0;
[UIView commitAnimations];
}
- (void)fadeComplete{
[self removeFromSuperview];
}
If I instead simply do
[self removeFromSuperView] without the alpha animation, there is no leaks reported.
See the screenshot below for Instruments details.
Instruments Screenshot
A sample stack trace:
0 libobjc.A.dylib _malloc_internal
1 libobjc.A.dylib _cache_addForwardEntry
2 libobjc.A.dylib lookUpMethod
3 libobjc.A.dylib class_respondsToSelector
4 CoreFoundation -[NSObject respondsToSelector:]
5 UIKit -[UINavigationTransitionView transition:fromView:toView:]
6 UIKit -[UINavigationTransitionView transition:toView:]
7 UIKit -[UINavigationController _startTransition:fromViewController:toViewController:]
8 UIKit -[UINavigationController _startDeferredTransitionIfNeeded]
9 UIKit -[UINavigationController viewWillLayoutSubviews]
10 UIKit -[UILayoutContainerView layoutSubviews]
11 UIKit -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
12 QuartzCore -[CALayer layoutSublayers]
13 QuartzCore CALayerLayoutIfNeeded
14 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
15 QuartzCore CA::Transaction::commit()
16 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
17 CoreFoundation __CFRunLoopDoObservers
18 CoreFoundation CFRunLoopRunSpecific
19 CoreFoundation CFRunLoopRunInMode
20 GraphicsServices GSEventRunModal
21 GraphicsServices GSEventRun
22 UIKit -[UIApplication _run]
23 UIKit UIApplicationMain
24 Client main **/main.m:14
25 Client start
And another one:
0 libobjc.A.dylib _malloc_internal
1 libobjc.A.dylib _cache_addForwardEntry
2 libobjc.A.dylib lookUpMethod
3 libobjc.A.dylib class_respondsToSelector
4 CoreFoundation -[NSObject respondsToSelector:]
5 UIKit -[UIViewAnimationState animationDidStart:]
6 QuartzCore run_animation_callbacks(double, void*)
7 QuartzCore CA::timer_callback(__CFRunLoopTimer*, void*)
8 CoreFoundation CFRunLoopRunSpecific
9 CoreFoundation CFRunLoopRunInMode
10 GraphicsServices GSEventRunModal
11 GraphicsServices GSEventRun
12 UIKit -[UIApplication _run]
13 UIKit UIApplicationMain
14 Client main ***/main.m:14
15 Client start
You didn't specify if you did your checks on the simulator on an actual device, but in my experience running Leaks in the simulator is not very reliable and will report many tiny leaks in the the SDK, while running it on the device will not report any leaks.
Are you sure your delegate method is being called? I think the problem is the animation delegate method, which, according to Apple's documentation, must have this signature:
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
And then you have a method like this in your class:
#pragma mark -
#pragma mark UIView animation delegate method
- (void)animationFinished:(NSString *)animationID
finished:(BOOL)finished
context:(void *)context
{
[self removeFromSuperview];
}
Probably your animation delegate is not being called, thus, the object is not released.
From the documentation:
setAnimationDidStopSelector:
Sets the message to send to the animation delegate when animation stops.
(void)setAnimationDidStopSelector:(SEL)selector
Parameters
selector
The message sent to the animation delegate after animations end. The default value is NULL. The selector should be of the form: - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context. Your method must take the following arguments:
animationID
An NSString containing an optional application-supplied identifier. This is the identifier that is passed to the beginAnimations:context: method. This argument can be nil.
finished
An NSNumber object containing a Boolean value. The value is YES if the animation ran to completion before it stopped or NO if it did not.
context
An optional application-supplied context. This is the context data passed to the beginAnimations:context: method. This argument can be nil.
Hope this helps!