views:

75

answers:

3

I'm developing an iphone application and i have small problem on it. I'm using popup caller methods into my appdelegate.m file bellow like that

-(void)OpenInfo{
    InfoDetail *detail = [[InfoDetail alloc] initWithNibName:@"InfoDetail" bundle:nil];
    self.infoDetail = detail;
    [detail release];
    [window addSubview:detail.view];
 }

-(void)OpenNetworkSelection{
    NetworkSelection *netsel = [[NetworkSelection alloc] initWithNibName:@"NetworkSelection" bundle:nil] ;
    self.networkselection = netsel;
    [netsel release];
    [window addSubview:netsel.view];
 }

And I'm calling these methods from inside of views like that

StatusFoxAppDelegate *delegate = (StatusFoxAppDelegate*)[[UIApplication sharedApplication] delegate];
[delegate OpenInfo];

And these helper views and opener views communicating via NSNotificationCenter.

My problem is as you can see "OpenInfo" and "OpenNetworkSelection" methods contains view instance creation logics.

When i called OpenInfo method it's working perfect as should be. But "OpenNetworkSelection" isn't working it's throwing when i tried second time *** -[UIButton release]: message sent to deallocated instance 0x3dbdb50 error.

Ok I understood that. Then i put NSlog line into the Dealloc overload of NetworkSelection.m
and OpenInfo.m files, because i need to differences of behaviours.

So, OpenInfo dealloc methods is working on when the view closed (I mean removed from superview). But NetworkSelection's dealloc method executing three times. I didn't find to problem source.

Can someone tell me, what i'm doing wrong ?

Thank you

Edit :

Guys, i found something wrong into my NetworkSelection view controller. More description is; i saw these lines of code into my viewcontroller.

    CommonGateway *gw = [[CommonGateway alloc] InitWithDefaults];
self.gateway = gw;
[self.gateway GetAvailableNetworkList];
[self.gateway setCommDelegate:self];
[gw release];

In these lines of code i'm making async server calls, when i commented out these lines, my viewcontroller worked perfectly, then i created "LoadDataFromServer" method and i passed CommonGateway instance from source that appdelage like that

- (void)LoadDataFromServer{
CommonGateway *gw = [[CommonGateway alloc] InitWithDefaults];
self.gateway = gw;
[self.gateway GetAvailableNetworkList];
[self.gateway setCommDelegate:self];
[gw release]; 
   }

My appdelegate code change to;

-(void)OpenNetworkSelection{
NetworkSelection *netsel = [[NetworkSelection alloc] initWithNibName:@"NetworkSelection" bundle:nil] ;
self.networkselection = netsel;
self.networkselection.gateway = commonGateway;
[netsel release];
[window addSubview:self.networkselection.view];
[self.networkselection LoadDataFromServer];
  }

But result same, if i comment out "[self.networkselection LoadDataFromServer];" line then it's working. And my CommonGateway class notify to caller via NSNotificationCenter.

I think it will be gives more clue for solving problem.

Thank you again

+4  A: 

You release detail here:

[detail release];

And then you try to use it immediately afterwards:

[window addSubview:detail.view];

Your application crashes because you released detail but you still tried to access its (now non-existent) properties.

So you may want to use, instead, your ivars, e.g.:

[window addSubview:self.infoDetail.view];

Or:

[window addSubview:[self.infoDetail view]];

You may want to read through Apple's Memory Management Programming Guide.

Alex Reynolds
They're both pointing to the same object so it doesn't matter if you use detail or self.infoDetail, they're both the same object (which is still retained if self.infoDetail is defined as a propery with retain set).
deanWombourne
Alex, thank you for your quick response. I tried your suggestion before, it's like that-(void)OpenInfo{ InfoDetail *detail = [[InfoDetail alloc] initWithNibName:@"InfoDetail" bundle:nil]; self.infoDetail = detail; [detail release]; [window addSubview:self.infoDetail.view];}-(void)OpenNetworkSelection{ NetworkSelection *netsel = [[NetworkSelection alloc] initWithNibName:@"NetworkSelection" bundle:nil] ; self.networkselection = netsel; [netsel release]; [window addSubview:self.networkselection.view];}Result is same error.
fyasar
If you release an object, it may no longer point to anything useful. Which, indeed, is confirmed by the "message sent to deallocated instance" error. Since the ivar (`infoDetail`) is taking ownership, it should be used, instead.
Alex Reynolds
If `infoDetail` has taken ownership, i.e. it is `retain`-ing the temporary `detail` instance, then you should not get the error. It may help if you post the `@property` statement from your header file, for your ivars `infoDetail` and `networkselection`.
Alex Reynolds
Dean is correct that this isn't the bug itself, but it's extremely dangerous code and suggests that you're doing similar memory mismanagement elsewhere (probably around the UIButton that you're actually having trouble with). This posting may be of help: http://robnapier.net/blog/three-magic-words-6
Rob Napier
This is definately 100% not the problem, both pointers are pointing to the same object so it doesn't matter in the slightest which one is used. Also, he's tested it both ways and the error is still there so the error must be somewhere else!
deanWombourne
Because the ivar is not being used properly, I'm inclined to believe there are likely other problems we can't see, as well.
Alex Reynolds
Actually i believe that problem into my view because other InfoDetailView working correctly. So, how can i trace and find the problem source ? I tried a lot of thinks and i stacked into this view.
fyasar
Based on what you have shown so far, you are likely not managing your objects' memory correctly, and we can't see other potential problems from the code you have provided.
Alex Reynolds
+1 for the Memory Management Guide. Everyone should read it.
Ben S
Hi Alex, I updated my post, could you please read again ?
fyasar
It may help if you post the `@property` statement from your header file, for your ivars, including `infoDetail` and `networkselection` and others. You may also want to post the code for `CommonGateway`. You may also want to follow naming conventions for methods, for example, making method names start with lowercase letter.
Alex Reynolds
A: 

If your getting a call to dealloc three times then that suggest that you have three instances of the same class instead of one. You should set a breakpoint in the dealloc and check the address of the instance to see if it is the same each time. I suspect it won't be.

However, if you did not make a call to [super dealloc] when you overrode dealloc it's possible the object isn't actually being deallocated but is just releasing its iVars. In that case, the system might call the same instance's dealloc repeatedly while trying to kill it.

TechZen
TechZen thank you for your post, it gave me an idea about my codes, then i found my problem as i described
fyasar
A: 

Guys i found my problem source. Problem exactly inside of the CommonGateway class implementation In this class i'm using constructor that

-(id)InitWithDefaults{
self = [super init];
NSOperationQueue *_queue = [[[NSOperationQueue alloc] init] autorelease];
self.queue = _queue;
[_queue release];
return self;

}

But that line is wrong, bacause i'm using this CommonGateway class a lot of place of my project. When i changed

NSOperationQueue *_queue = [[[NSOperationQueue alloc] init] autorelease];

to

NSOperationQueue *_queue = [[NSOperationQueue alloc] init];

It's working again.

Guys, thank you very much for your support.

fyasar
You should select the checkmark next to this answer so the system knows the question has been resolved.
TechZen