iPhone memory leak help - iphone

This code is leaking, the performance tool blames two leaks on this block of code. If i comment it out the leak doesn't happen. Any help pinning it down would be greatly appreciated.
Leaks:
Malloc 48 bytes
NSCFarray 32 bytes
Code Block:
NSArray *myArray = [[NSArray alloc] initWithObjects: #"Add", #"Edit", nil];
segmentControl = [[UISegmentedControl alloc] initWithItems:myArray];
[myArray release];
[segmentControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[segmentControl setMomentary:YES];
[segmentControl addTarget:self action:#selector(addOrEditPressed) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *myBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:segmentControl];
self.navigationItem.rightBarButtonItem = myBarButtonItem;
[myBarButtonItem release];

As long as segmentControl is nil when you enter the code block and is being released somewhere else in your code (like dealloc or viewDidUnload) then you are doing nothing wrong.
Have you tried running your code under the static analyzer (Xcode menu: Build | Build & Analyze)?
Instruments can sometimes generate false positives when searching for leaks. If the leaked memory doesn't accumulate over time, your worst case scenario is that your program is leaking a total of 80 bytes. Leaks that grow over time are what you should be concerned about.

Is segmentControl meant to be released?

myArray's retain count is still one after this section of code. When you add it to the initWithItems to create the segmentControl, it now has a reference to the object.
Is that possibly the leak?

Is segmentControl a property? Do you nil it in viewDidUnload?

No alloc is required when you create the array.
NSArray *myArray = [[NSArray alloc] initWithObjects: #"Add", #"Edit",
nil];
Use :
+ (id)arrayWithObjects:(id)firstObj, ...
Try it this way, this also doesn't needs release.

Related

UIImage isKindOfClass issue

This is my code in my application,
[imageview setAlpha:1.0f];
[imageview setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#.png",[pages objectAtIndex:swipeCount]]]];
[imageview setFrame:CGRectMake(-300, 0, 1368, 1000)];
Edit:
pages = [[NSArray alloc] initWithObjects:#"page1",#"page2",#"page3",#"page4",#"page5",#"page6",#"page7b",#"page8",#"page9",#"page10a",#"page11",#"page12",#"page13b",#"page14",#"page15",#"page16a",#"page17",#"page18",#"page19",#"page20",#"page21",#"page22",#"page23",#"page24",#"page25", nil];
imageview=[[UIImageView alloc]init];
its working properly, problems except when the app enters background and comes back to foreground shows the following error,
*** -[UIImage isKindOfClass:]: message sent to deallocated instance 0x1e8b10
What wrong with the code?
Please help me out
Yes, you need to allocate memory to your UIImage. What is basically happening is that your image is being temporarily stored in the memory and deallocated upon closing the app so iOS could allocate that memory to more immediate needs. You can fix that as below. I'm also gonna allocate a string since stringWithFormat returns an autorelease String.
NSString *imageName = [[NSString alloc] initWithFormat::#"%#.png",[pages objectAtIndex:swipeCount]];
UIImage *myImage = [UIImage imageNamed:myImage];
[imageview setImage:image];
Try using properties. Make array,imageView as a property and then use
self.pages and self.imageView
see this good article on properties
Objective-c properties

alloc initWithObjects vs arrayWithObject

I don't understand why if I write these code
icons = [[NSArray alloc] initWithObjects:
#"appointment",
#"work",
#"anniversary",
#"me",
nil];
the app crashed. But then I replaced by these code
icons = [NSArray alloc] arrayWithObjects:
#"appointment",
#"work",
#"anniversary",
#"me",
nil];
and the app did't crash.
But there is the same affect between these methods !
I don't know why ? Can u help me ?
initWithObjects method means you have to release the object of array whenever this is not required as this is instance method and for more details click:
arrayWithObjects method means you don't need to release the object of array whenever this is not required as this is class method and for more details click:
If you are not clear with the points so revert me..

Is it ok to autorelease UIViewControllers?

I have some view controllers:
StockTwitsTVViewController* stvViewController = [[[StockTwitsTVViewController alloc] initWithNibName:#"StockTwitsTVViewController" bundle:nil]autorelease];
UINavigationController *stvNavController = [[UINavigationController alloc] initWithRootViewController:stvViewController];
stvNavController.tabBarItem.image = [UIImage imageNamed:#"today-icon.png"];
ScheduleViewController* scheduleViewController = [[[ScheduleViewController alloc] initWithNibName:#"ScheduleViewController" bundle:nil]autorelease];
scheduleViewController.title = #"Archives";
UINavigationController *scheduleNavController = [[UINavigationController alloc] initWithRootViewController:scheduleViewController];
scheduleNavController.tabBarItem.image = [UIImage imageNamed:#"archived-icon.png"];
stvTabBarController = [[UITabBarController alloc] init];
stvTabBarController.delegate = self;
stvTabBarController.viewControllers = [NSArray arrayWithObjects:stvNavController, scheduleNavController, nil];
stvTabBarController.selectedViewController = stvNavController;
[stvNavController release];
[scheduleNavController release];
[self presentModalViewController:stvTabBarController animated:YES];
Is it ok to auto-release them or is it better practice to manually release? Why?
What you do in your code is perfectly fine. To make things more consistent I would also create stdNavController and scheduleNavController as autoreleased objects.
Read mikeash.com: Autorelease is Fast.
What he didn't test was autorelease versus release. When I tested, a million [[[NSObject alloc] init] autorelease] plus the autorelease pool overhead took on the order of twice as long as [[[NSObject alloc] init] release]. Admittedly, I tested on 10.6 (presumably if it's still refcounted since I didn't enable GC), but the relative performance still holds.
Maybe autorelease uses a couple of microseconds of CPU time, but it sure beats adding a memory leak because you changed an ivar to a local, or you copy-pasted code around and forgot the release.
Care about performance when it matters. When it does, you might decide to use CFString instead of NSString and ivar access instead of property access and function calls instead of class methods. In general, though, it's important to write code that is easy to maintain, even if that means using 1% more CPU.
The autorelease will let the release to be done later by the OS, it means when the current run loop finishes.
The release inform the OS that the object id not necessary anymore and that the allocated memory can be freed.
For performance on iOS it's better to use release, instead of autorelease because the system can claim back the allocated memory straightaway.

NSMutableArray withObject(UIImageView *)

I am trying to load an NSMutableArray with UIImageViews. Everything is going fine with that.
Unfortunately, I have no idea how to use the objects when they are in the mutable array.
Here is some code:
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
NSMutableArray *array = [NSMutableArray new];
[array loadWithObject:(UIImageView *)imageView];
[imageView release];
That kind of sets up what I've done. Here's what I want to do:
[array objectAtIndex:5].center = GCRectMake(0, 0);
but that doesn't work. How can I do this??
OK, I'll explain the problems you're having. The way to do what you are trying to do is the following:
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
NSArray *array = [NSArray arrayWithObject:imageView];
[imageView release];
[[array objectAtIndex:0] setCenter:CGPointMake(0.0,0.0)];
First, there is no method -[NSMutableArray loadWithObject:]. Likewise, for your example, you don't really even need a mutable array. Mutable objects have their place, but I usually try to use immutable ones when it makes sense to; as such, I've used NSArray.
Next, you never need to typecast objects when you're adding them to an array. There are a few reasons wherefore your example didn't work:
You were accessing the sixth (starting at one) object in the array. Was there an instance of UIImageView at that index?
For some reason, dot-notation for getters and setters only works when the compiler knows the type of the object you're sending a message to. Since the type of an object that is coming out of an array is not clear at compile-time, you can't use dot-notation. Instead, just use old-fashioned Objective-C method-sending syntax ("brackets and colons").
Finally, it's Core Graphics, not Gore Craphics: hence the prefix is CG, not GC. Also, -[UIImageView setCenter:] takes a CGPoint, not CGRect. So the function you wanted was CGPointMake.
Best of luck to you! Let me know if this helps clear some things up.
I think you should refer NSMutableArray.
However, I am just giving an overview of NSMutableArray.
NSMutableArray = Next Step (NS) Mutable Array
Mutable means array can be modified as and when required.
Now, This mutable array can hold any kind of objects.
Assume that I want to store strings in an array. I would write following statements.
NSMutableArray *anArray=[[NSMutableArray alloc] init];
[anArray addObject:#"Sagar"];
[anArray addObject:#"pureman"];
[anArray addObject:#"Samir"];
Here, I found that you need to store imageViews in your requirements.
NSMutableArray *anArray=[[NSMutableArray alloc] init];
UIImageView *imgV1=[[UIImageView alloc] initWithFrame:CGRectMake(10,50,60,70)];
UIImageView *imgV2=[[UIImageView alloc] initWithFrame:CGRectMake(10,110,60,70)];
UIImageView *imgV3=[[UIImageView alloc] initWithFrame:CGRectMake(10,170,60,70)];
UIImageView *imgV4=[[UIImageView alloc] initWithFrame:CGRectMake(10,210,60,70)];
[anArray addObject:imgV1];
[anArray addObject:imgV2];
[anArray addObject:imgV3];
[anArray addObject:imgV4];
Now, once ImageViews are added to array, release imageviews as array has it's retain count.
[imgV1 release];
[imgV2 release];
[imgV3 release];
[imgV4 release];
Above code will add images to NSMutableArray
When you use one of the image from an array, just write down this thing
UIImageView *x=[anArray objectAtIndex:0];
Hope Above descriptions work for you.
Add comment, if you don't understood.

Why is this code producing an memory leak?

The Leaks Instrument in Xcode shows me an memory leak here. I have commented the affected line which Leaks is complaining about. But I see no error in my memory management...
- (void)setupViewController {
MyViewController *myVC = [[MyViewController alloc] init];
UITabBarItem *tbi = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemDownloads tag:1];
myVC.tabBarItem = tbi; // LEAK: 128 bytes
self.myViewController = myVC;
[myVC release];
[tbi release];
}
I mean... tbi and myVC IS released at the end, and the alloc IS balanced. So what's wrong? I don't get it.
if MyVc.tabBarItem is already set, whatever it's pointing at may not be deallocated properly, causing a leak.
It just goes to show that at least one of the following statements is true:
Instruments is not perfect and sometimes shows leaks where there aren't any (and vice versa).
Apple's code is not bug-free.
In fact, both are true.