subview not showing on already displayed view - iphone

I'm new on iPhone development and I'm stuck with a subview not showing after the controller is notified to refresh these items.
So, it's my main page showing, showing the 3-last items of a newsfeed at the bottom.
The view controler handles the loading of the newsfeed (in a NSArray).
When loading the page, the newsfeed is correctly displayed as a subview of the main view. However, when the view already exists (for example just after login for the first time), the newsfeed is not displayed, or refresehed. The avatar images that are fetched from internet asynchronously are displayed correctly. But not the labels.
The debug shows that the code is correctly executed...but nothing happens...
Here is the code handling the notification and refresh.
I'm sure I miss something stupid but cannot put my finger on it.
Does an UILabel or UIImage of the subview can avoid the element to be refreshed?
Thanks for the help!
The controler code
-(void) handleRefreshNewsfeed:(NSNotification*)notification{
if (self.newsfeedMostRecentDate == nil){
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyyMMdd HH:mm"];
self.newsfeedMostRecentDate = [dateFormatter dateFromString:#"20100101 00:00"];
[dateFormatter release];
}
NSArray * newsfeed = [cdw getNewsfeedForUser:self.currentUser andLimit:self.newsfeedLimit];
if ([newsfeed count] > 0){
self.newsfeedMostRecentDate = [(Newsfeed *)[newsfeed objectAtIndex:0] posted];
if ([self.view isKindOfClass:[MenuView class]]){
[(MenuView *)self.view refreshNewsfeed:newsfeed];
}
}
}
The main view declaration:
#interface MenuView : UIView {
MenuNewsfeed * newsFeedView;
}
#property(nonatomic, retain) IBOutlet MenuNewsfeed *newsFeedView;
-(void)displayNewsfeed:(NSArray *)newsfeed;
-(void)refreshNewsfeed:(NSArray *)newsfeed;
The main view code :
-(void)displayNewsfeed:(NSArray *)newsfeed{
[self.newsFeedView setCurrentUser:currentUser];
[self.newsFeedView displayNewsfeed:newsfeed];
[UIView animateWithDuration:0.75f
delay: 0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.newsFeedView.alpha = 1.0;
}
completion:^(BOOL finished){
//nothing
}
];
}
-(void)refreshNewsfeed:(NSArray *)newsfeed{
if ([self.newsFeedView.newsfeed count] > 0){
[UIView animateWithDuration:0.50f
delay: 0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.newsFeedView.alpha = 0.0;
}
completion:^(BOOL finished){
// [self displayNewsfeed:newsfeed];
}
];
}else {
[self displayNewsfeed:newsfeed];
}
}
Michael

This may not answer your problem.
However, there is a small glitch that I can see. The CGRectMake (50, 100, 55, 12) will create a rect of 12px wight but 55px height.
Well, at least "te" or "tes" of your text should be visible as I do not see any insects. With some insect value (10 or so) it could happen that noting of your text string is visible.
Or no. When a text is clipped, depending on the default line break mode, it could be truncated to a certain extend and some "..." added at the end.
Could it be that you only see some points instead of "test test test"?
Otherwise check wether the tmp label is hidden by some other view, although it should be most on top of the view's stack.
But give it some realistic rect of maybe 20, 100, just to be save, before you do any further testing.

I've found out what the problem was : the code handling the notification (and modifying the UI) was not processed on the main thread.
[self performSelectorOnMainThread:#selector(refreshNewsfeed) withObject:notification.object waitUntilDone:NO];
Calling the refresh method via performSelectorOnMainThread solved the issue.

Related

UIAlertView Rendering Error

I have been working on an app for a couple of months now, but have finally run into an issue that I can't solve myself, and can't find anything on the internet to help.
I am using several normal UIAlertViews, in my app. Some have 2 buttons, some have 3 buttons, and a couple have 2 buttons and a text field. However all have the same issue. When you call [someAlertView show]; the alert view appears as normal, but then suddenly its graphics context seems to get corrupted as you can see from the screenshot.
This happens on both iPhone and iPad simulators (both 5.0 and 5.1), and happens on an iPad and iPhone4S device as well.
The image showing through is whatever happens to be behind the alertView.
The Alert still works, I can click the buttons, type in the text field, then when it dismisses the delegate methods are called correctly and everything goes back to normal. When the alertView appears again, the same thing happens.
The view behind the alert is a custom UIScrollView subclass with a content size of approximately 4000 pixels by 1000 with a UIImage as the background. The png file is mostly transparent, so is only about 80kB in memory size, and the phone is having no issues rendering it - the scroll view is still fully responsive and not slow.
It also has a CADisplayLink timer attached to it as part of the subclass. I have tried disabling this just before the alertView is shown, but it makes no difference so I am doubtful that is the issue.
This app is a partial rewrite of one I made for a university project, and that one could display UIAlertViews over the top of a scrollView of the same size and subclass without issue. The difference between this app and that one is that in my old app, I had subclassed UIAlertView to add extra things such as a pickerView, however I decided that I didn't like the way it looked so moved everything out of the alert and am just sticking with a standard UIAlertView.
This is how the alertView in the screenshot is called:
- (IBAction)loadSimulation:(id)sender {
importAlert = [[UIAlertView alloc] initWithTitle:#"Load Simulation" message:#"Enter Filename:" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Load", nil];
[importAlert setAlertViewStyle:UIAlertViewStylePlainTextInput];
[importAlert showPausingSimulation:self.simulationView]; //Calling [importAlert show]; makes no difference.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[self hideOrganiser]; //Not an issue as the problem occurs on iPad as well.
}
}
With this being the categorised AlertView to add the ability to stop the scrollViews CADisplay link.
#interface UIAlertView(pauseDisplayLink)
- (void)showPausingSimulation:(UILogicSimulatorView*)simulationView;
#end
#implementation UIAlertView(pauseDisplayLink)
- (void)showPausingSimulation:(UILogicSimulatorView *)simulationView {
[simulationView stopRunning];
[simulationView removeDisplayLink]; //displayLink needs to be removed from the run loop, otherwise it will keep going in the background and get corrupted.
[self show];
}
I get no memory warnings when this happens, so I am doubtful it is due to lack of resources.
Has anyone come across an issue like this before? If you need further information I can try to provide it, but I am limited in what code I can post. Any help would be appreciated, I've been trying to solve this for two weeks and can't figure it out.
Edit:
It appears that it is not the AlertView at all (or rather it is not just the alertView), as the problem goes away when I remove the scroll view behind it, so there must be some issue between the two. This is the code for my UIScrollView subclass:
.h file:
#import
#import
#class ECSimulatorController;
#interface UILogicSimulatorView : UIScrollView {
CADisplayLink *displayLink;
NSInteger _updateRate;
ECSimulatorController* _hostName;
}
#property (nonatomic) NSInteger updateRate;
#property (nonatomic, strong) ECSimulatorController* hostName;
- (void) removeDisplayLink;
- (void) reAddDisplayLink;
- (void) displayUpdated:(CADisplayLink*)timer;
- (void) startRunning;
- (void) stopRunning;
- (void) refreshRate:(NSInteger)rate;
- (void) setHost:(id)host;
- (void)setMinimumNumberOfTouches:(NSInteger)touches;
- (void)setMaximumNumberOfTouches:(NSInteger)touches;
#end
.m file:
#import "UILogicSimulatorView.h"
#import "ECSimulatorController.h"
#import <QuartzCore/QuartzCore.h>
#implementation UILogicSimulatorView
#synthesize updateRate = _updateRate;
#synthesize hostName = _hostName;
- (void)reAddDisplayLink {
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; //allows the display link to be re-added to the run loop after having been removed.
}
- (void)removeDisplayLink {
[displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; //allows the display link to be removed from the Run loop without deleting it. Removing it is essential to prevent corruption between the games and the simulator as both use CADisplay link, and only one can be in the run loop at a given moment.
}
- (void)startRunning {
[self refreshRate:self.updateRate];
[displayLink setPaused:NO];
}
- (void)refreshRate:(NSInteger)rate {
if (rate > 59) {
rate = 59; //prevent the rate from being set too an undefined value.
}
NSInteger frameInterval = 60 - rate; //rate is the number of frames to skip. There are 60FPS, so this converts to frame interval.
[displayLink setFrameInterval:frameInterval];
}
- (void)stopRunning {
[displayLink setPaused:YES];
}
- (void)displayUpdated:(CADisplayLink*)timer {
//call the function that the snakeController host needs to update
[self.hostName updateStates];
}
- (void)setHost:(ECSimulatorController*)host;
{
self.hostName = host; //Host allows the CADisplay link to call a selector in the object which created this one.
}
- (id)initWithFrame:(CGRect)frame
{
//Locates the UIScrollView's gesture recogniser
if(self = [super initWithFrame:frame])
{
[self setMinimumNumberOfTouches:2];
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(displayUpdated:)]; //CADisplayLink will update the logic gate states.
self.updateRate = 1;
[displayLink setPaused:YES];
}
return self;
}
- (void)setMinimumNumberOfTouches:(NSInteger)touches{
for (UIGestureRecognizer *gestureRecognizer in [self gestureRecognizers])
{
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
//Changes the minimum number of touches to 'touches'. This allows the UIPanGestureRecogniser in the object which created this one to work with one finger.
[(UIPanGestureRecognizer*)gestureRecognizer setMinimumNumberOfTouches:touches];
}
}
}
- (void)setMaximumNumberOfTouches:(NSInteger)touches{
for (UIGestureRecognizer *gestureRecognizer in [self gestureRecognizers])
{
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
//Changes the maximum number of touches to 'touches'. This allows the UIPanGestureRecogniser in the object which created this one to work with one finger.
[(UIPanGestureRecognizer*)gestureRecognizer setMaximumNumberOfTouches:touches];
}
}
}
#end
Well, I have managed to come up a solution to this. Really it is probably just masking the issue rather than finding the route cause, but at this point I will take it.
First some code:
#interface UIView (ViewCapture)
- (UIImage*)captureView;
- (UIImage*)captureViewInRect:(CGRect)rect;
#end
#implementation UIView (ViewCapture)
- (UIImage*)captureView {
return [self captureViewInRect:self.frame];
}
- (UIImage*)captureViewInRect:(CGRect)rect
{
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenShot;
}
#end
- (void)showPausingSimulation:(UILogicSimulatorView *)simulationView {
[simulationView stopRunning];
UIView* superView = simulationView.superview;
CGPoint oldOffset = simulationView.contentOffset;
for (UIView* subview in simulationView.subviews) {
//offset subviews so they appear when content offset is (0,0)
CGRect frame = subview.frame;
frame.origin.x -= oldOffset.x;
frame.origin.y -= oldOffset.y;
subview.frame = frame;
}
simulationView.contentOffset = CGPointZero; //set the offset to (0,0)
UIImage* image = [simulationView captureView]; //Capture the frame of the scrollview
simulationView.contentOffset = oldOffset; //restore the old offset
for (UIView* subview in simulationView.subviews) {
//Restore the original positions of the subviews
CGRect frame = subview.frame;
frame.origin.x += oldOffset.x;
frame.origin.y += oldOffset.y;
subview.frame = frame;
}
[simulationView setHidden:YES];
UIImageView* imageView = [[UIImageView alloc] initWithFrame:simulationView.frame];
[imageView setImage:image];
[imageView setTag:999];
[superView addSubview:imageView];
[imageView setHidden:NO];
superView = nil;
imageView = nil;
image = nil;
[self show];
}
- (void)dismissUnpausingSimulation:(UILogicSimulatorView *)simulationView {
UIView* superView = simulationView.superview;
UIImageView* imageView = (UIImageView*)[superView viewWithTag:999];
[imageView removeFromSuperview];
imageView = nil;
superView = nil;
[simulationView setHidden:NO];
[simulationView startRunning];
}
Then modifying the dismiss delegate method in my class to have this line:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[alertView dismissUnpausingSimulation:self.simulationView];
...
When the alert view is called, but before it is shown, I need to hide the simulator to prevent it corrupting the alert. However just hiding it is ugly as then all is visible behind is a empty view.
To fix this, I first make a UIImage from the simulator views graphics context. I then create a UIImageView with the same frame as the simulator and set the UIImage as its image.
I then hide the simulator view (curing the alert issue), and add my new UIImageView to the simulators superview. I also set the tag of the image view so I can find it later.
When the alert dismisses, the image view is then recovered based on its tag, and removed from its superview. The simulator is then unhidden.
The result is that the rendering issue is gone.
I know its too late for an answer to this question. Lately I had experianced this very same issue.
My Case:
Added couple of custom UIViews with background images and some controlls to the scroll view with shadow effect. I had also set the shadowOffset.
The Solution:
After some step by step analysis, I found out that setting the setShadowOpacity caused The rendering problem for me. When i commented that line of code, it cured the UIAlertView back to normal appearance.
More:
To make sure, I created a new project mimicing the original ui with shadowOpacity. But it didnt caused the rendering problem as i expected. So I am not sure about the root cause. For me it was setShadowOpacity.

Strange memory leak in Window:addSubView

first of all sorry for my English :-) not so good.
I have a strange memory leak with the following code (code after the explanation).
I have a class, FLWaitingView. It is a simple view with a waiting indicator (plus a view with background), used to say to the user "wait for the data to be loaded".
It has two simple methods: show and dismiss.
In the show method, I find the main Application Window and add the subviews (the waiting view and a background view, with different animations). In the dismiss method, I remove it from superview.
In every show, I verify that the view isn't already visible using a static bool var (is_visible).
The strange thing is this: In the dismiss method, I use:
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
to remove the two views from the Window, to avoid them to be retained. They are correctly removed, I can verify this with NSLog (for cicle on each window subview). But, in INSTRUMENTS, using the "mark heap" function, I see that in every single reload (new instance of FLWaitingView, then show, then dismiss) the old instance remains in memory and continues to increase memory usage. Obviously is not a problem of the calling code, because I correctly release the object:
//CALLING CODE
//customWaitingView is a property retained
self.customWaitingView = [[[FLWaitingView alloc]init]autorelease];
[self.customWaitingView show];
Moreover, and I think that this is the most important information, if I move the view dismission in another method, called by a selector, the leak disappear!!!
Now I show the "wrong" code and, after, the "correction". I would like to understand why it happens.
- (void)show
{
if (!is_visible){
id appDelegate = [[UIApplication sharedApplication] delegate];
UIWindow *window = [appDelegate window];
self.waitingLabel.text = #"Attendere";
self.view.alpha = 1.0;
self.waitingView.alpha = 1.0;
[window addSubview:self.view];
[window addSubview:self.waitingView];
[self.waitingIndicator startAnimating];
self.view.frame = window.frame;
self.waitingView.center = window.center;
// "Pop in" animation for alert
[self doPopInAnimationWithDelegate:self];
// "Fade in" animation for background
[self doFadeInAnimation];
is_visible = YES;
} else {
NSLog(#"FLWaitingView %# already visible, do nothing", self);
}
}
- (void)dismiss
{
[UIView beginAnimations:nil context:nil];
self.view.alpha = 0.0;
self.waitingView.alpha = 0.0;
[UIView commitAnimations];
[self.waitingIndicator stopAnimating];
//here is the problem
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
is_visible = NO;
}
the code above is the "wrong" one, but if I add
[self performSelector:#selector(alertDidFadeOut) withObject:nil afterDelay:0.5];
in the dismiss method and a new method (obviously removing the redundant code from dismiss method):
- (void)alertDidFadeOut
{
//here the memory is correctly released
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
is_visible = NO;
}
the memory is correctly released.
Why??????
Thank you in advance
Fabio
Your view isn't getting released as you would be expecting because at the moment you're releasing it there are still animations linked to it. You can only properly release it after the animations are finished.
Your second method works because the animation lasts less than 0.5 seconds - the releasing code is called after view is freed of all the animations.
Proper way to animate the view would be to either create an animation and assign its delegate or maybe a bit more elegant soulution is to use block-based animation like this:
- (void)dismiss
{
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[UIView animateWithDuration: 0.15
animations: ^{
self.view.alpha = 0.0;
self.waitingView.alpha = 0.0;
}
completion: ^(BOOL finished){
[self.waitingIndicator stopAnimating];
    [self.view removeFromSuperview];
    [self.waitingView removeFromSuperview];
    is_visible = NO;
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}];
}

Show PDF on a UIScrollView

I found an example code for showing PDF file on a UIScrollView with horizontal scrolling. It works fine, but problem is it shows only 2 pages of PDF. I tried in my best to figure out the issue, but I couldn't figure it. Can you please give me help?
I looked at that sample project you pointed to in this question and like you, I can see it only displays two pages of whatever PDF file it's given to display.
The problem with the sample code comes in the PDFViewController.m file. For these lines:
PDFScrollView *page = [self dequeueRecycledPage];
if (page == nil) {
page = [[[PDFScrollView alloc] initWithPage:index + 1 frame:[self frameForPageAtIndex:index]] autorelease];
}
I added
else {
[page setPage: index inFrame:[self frameForPageAtIndex: index]];
}
And also these new lines into PDFScrollView.h
- (void) setPage: (NSInteger) onPage inFrame:(CGRect)frame;
And PDFScrollView.m
- (void) setPage: (NSInteger) onPage inFrame:(CGRect) frame
{
if(pdfView)
{
[pdfView removeFromSuperview];
[pdfView release];
}
self.frame = frame;
self.index = onPage;
pdfView = [[PDFViewTiled alloc] initWithPage:onPage frame:self.frame];
[self addSubview:pdfView];
}
This isn't a perfect fix. You'll see the drawing isn't proper, especially when backing up pages. I'll leave that to you as an exercise to take care of, but hopefully this is a nice start.
And I hope it helps you out.

Problem with removing a subview and then adding it again

I have a problem with removing a subview, or more precisely with checking if it is still there after having deleted it.
My app first adds a subview to self.view.
[self.view addSubview:tabsClippedView];
Then it adds another subview to this subview (to which it adds several buttons as subviews, but I guess this is unimportant in this context):
[tabsClippedView addSubview:tabsView];
Finally, I have a method which allows the tabsView to be deleted and then created again. I need to do this so as to update the number of buttons in that tabsView (as the user can delete buttons). The method looks basically like this:
[self.tabsView removeFromSuperview];
After that I call a method called showTabs (which I already called in the very beginning of the app in order to add the subViews). This is where it all becomes problematic and where my app crashes (I get no error in the debug console, so I don't really know what the issue is...):
if ([tabsClippedView isDescendantOfView:self.view]) {
NSLog(#"There is already a tabsClippedView.");
} else {
NSLog(#"There is no tabsClippedView. I'll add one...");
[self initTabsClippedView];
}
This is where the app crashes: when trying to assess if tabsView isDescendantOfView (I don't get any of the following logs):
if ([tabsView isDescendantOfView:tabsClippedView]) {
NSLog(#"There is already a tabsView");
} else {
NSLog(#"There is no tabsView for the buttons. I'll add one including buttons.");
[self initTabs];
}
I'd be grateful for any suggestions where the problem could be.
EDIT:
These are the methods to set up my views:
-(void) initTabsClippedView { // sets up tabsClippedView
NSLog(#"initTabsClippedView method started...");
CGRect tabsClippedFrame = CGRectMake(258,30,70,81*6);
tabsClippedView = [[[UIView alloc] initWithFrame:tabsClippedFrame] autorelease];
tabsClippedView.clipsToBounds = true;
[self.view addSubview:tabsClippedView];
NSLog(#"initTabsClippedView method ended.");
}
-(void) initTabs {
NSLog(#"initTabs started. Adding buttons to tabsClippedView...");
CGRect tabsFrame = CGRectMake(-30,0,50,480);
tabsView = [[[UIView alloc] initWithFrame:tabsFrame] autorelease];
[tabsClippedView addSubview:tabsView];
// sets up buttons in tabsClippedView
And this is where I delete the tabsClippedView (triggered by a button found in tabsClippedView):
-(void)tabDelete:(id)sender
{
UIButton *button = (UIButton *)sender;
[UIView animateWithDuration:0.75
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
button.transform = CGAffineTransformMakeTranslation(-30, 0);
}
completion:^(BOOL finished){
[UIView animateWithDuration:0
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[self.tabsView removeFromSuperview];
//...
}
completion:^(BOOL finished){
NSLog(#"tabsView removed from Superview. Objects Deleted.");
[self showTabs];
NSLog(#"TabDelete finished. Button removed and tabsView updated accordingly.");
}
];
}];
And this is the showTabs method which was already called when I started the app:
-(void)showTabs {
NSLog(#"showTabs started...");
currentView = #"Tabs";
if ([tabsClippedView isDescendantOfView:self.view]) {
NSLog(#"There is already a tabsClippedView.");
} else {
NSLog(#"There is no tabsClippedView. I'll add one...");
[self initTabsClippedView];
}
if ([tabsView isDescendantOfView:tabsClippedView]) {
NSLog(#"There is already a tabsView");
} else {
NSLog(#"There is no tabsView for the buttons. I'll add one including buttons.");
[self initTabs];
}
Is it possible that you are getting EXC_BAD_ACCESS? Is it possible that the app is crashing because tabsView is deallocated when you send isDescendantOfView: to it. If you run with breakpoints enabled it should tell you the reason for the crash. If it is an EXC_BAD_ACCESS problem you should try NSZombie.
To activate NSZombie do the following:
Get info of the executable.
Go to the arguments tab.
In the "Variables to be set in the environment:" section add:
Name: NSZombieEnabled
Value: YES
Then run your app as usual and when it crashes it should tell you which deallocated object received what message.
EDIT: Just saw your edit. I think I nailed it. You're autoreleasing the views when you create them, so when they are removed from their superviews they are no longer retained and thus deallocated. You're app crashes because you're trying to run methods on deallocated views.
EDIT 2: Thought I should tell you that there is a better solution than the one posted by Praveen S.
Change your code as follows:
[tabsClippedView release];
tabsClippedView = [[UIView alloc] initWithFrame:tabsClippedFrame];
and
[tabsView release];
tabsView = [[UIView alloc] initWithFrame:tabsFrame];
The above code does the same thing as the code posted by Praveen S, but without the autorelease. An autorelease is more expensive than a regular release and should only be used when needed and in this case it isn't.
Rather than releasing before you allocate a new view you probably want to release the view when you're done with it:
[tabsView removeFromSuperview];
[tabsView release];
tabsView = nil;
or simply
[tabsView removeFromSuperview];
self.tabsView = nil;
and then instead of:
if ([tabsView isDescendantOfView:tabsClippedView]) ...
you can use:
if (tabsView) ...
As you might have noticed, there really is no need for you to retain the view. You could just as well do the following:
tabsView = [[UIView alloc] initWithFrame:tabsFrame];
[tabsClippedView addSubview:tabsView]; // This retains tabsView
[tabsView release];
and then to remove the view you would use:
[tabsView removeFromSuperview]; // This will release the tabsView
tabsView = nil;
Also remember to set the views to nil in viewDidUnload.
EDIT 3: Why self made such a difference:
What you need to understand is how properties and reference counting works. There are books and such you could read about it. I'm sure Google can provide you with some good references as well.
The difference between
self.tabsView = [[UIView alloc] initWithFrame:frame];
and
tabsView = [[UIView alloc] initWithFrame:frame];
is that self.tabsView is accessing the properties setter, while tabsView is accessing the instance variable directly.
A nonatomic, retain property's implementation looks something like the following:
- (void)setTabsView:(UIView *)view
{
if (view != tabsView) {
[tabsView release];
tabsView = [view retain];
}
}
So the property is taking care of the memory management for you. In my solution I take care of the memory management myself and thus I don't need the property to do it for me, so I don't use it.
I hope this explains why self made such a difference.
Change your code as follows:
self.tabsClippedView = [[[UIView alloc] initWithFrame:tabsClippedFrame] autorelease];
and
self.tabsView = [[[UIView alloc] initWithFrame:tabsFrame] autorelease];

How to release a viewcontroller while using addSubview?

I've the code as below:
+(void) addHeader:(UIViewController*) hostViewController requiresBackBtn:(BOOL)BooleanValue
{
ApplicationHeader *appHeader = [[ApplicationHeader alloc] initWithNibName:#"ApplicationHeader" bundle:nil];
appHeader.hostViewController = hostViewController;
[appHeader.view setFrame:CGRectZero];
[hostViewController.view addSubview:appHeader.view];
if (BooleanValue) {
[appHeader.view setFrame:CGRectMake(0, 0, 320, 97)];
}
else {
[appHeader.backBtn setHidden:TRUE];
[appHeader.view setFrame:CGRectMake(0, 0, 320, 74)];
}
// [appHeader release]; // This call tends to app Crash!!!!!
}
If I call release to appHeader then the app crashes I press the button which found in appHeader!!
And if I doesn't this is a memory leak.
What to do now?
:(
I don't know what an ApplicationHeader is, but I know that yours has a retained view from
[hostViewController.view addSubview:appHeader.view];
Would ApplicationHeader be better as a subclass of UIView? Without more information, I'm not sure what to suggest as a solution but I think you need to rethink what you are trying to accomplish.
Adding other controller's view in your viewController is against Apple's "one controller per screen" policy. It will surely give level 1 and 2 memory warnings and app will crash intempestively.