Hello,

I have the following issue:

The code below shows a brief snippet of a view controller. Its responsibility - 
besides managing the views - is to create a URL request, and using a 
UIConnection to download data. Then, the data - a JSON format - will be parsed. 
The result is a dictionary from which I need certain fields which in turn shall 
be displayed in labels residing in the view controllers view.

The URL request will be done in a separate thread and yields data which is 
actually a JSON format (not shown in the code snipped). 

The parsing will be performed within yet another thread. Its main method is 
shown below.

The JSON parser returns an NSDictionary instance from which I need certain 
fields. These values will be used to set the text property of labels  which 
reside in the view controller.

There is a label "nameLabel" which text needs to be set from a certain field in 
the dictionary.  I don't want to set the label's text property directly in the 
main thread's method - instead I use an NSString instance called "name" to 
store the text. This is an ivar, see property declaration below.
Before the thread is finished and returns, it schedules the method 
-upadateLabels on the main thread which finally sets the label's text property  
(shown below).

Here is the issue:

Once the auto release pool gets released, the ivar "name" becomes invalid - as 
if it has been deallocated by the pool.

I don't see why this should happen, since I think I get a copy of the string - 
as the property declaration implies: @property (copy) NSString* name.

Do I miss something fundamentally?

I need to mention, this is code on the iPhone - no GC


Thanks in advance for pointing me to the solution.


Regards
Andreas


//  MainViewController.m
@interface MainViewController ()
@property (nonatomic, retain) IBOutlet UILabel*         nameLabel;
@property (copy)                       NSString*        name;
@end

@implementation MainViewController

@synthesize name;
@synthesize nameLabel;


- (void)threadMain:(NSData *)data 
{
    NSAutoreleasePool*  pool = [[NSAutoreleasePool alloc] init];
    NSString*           jsonResponse = nil;
    SBJsonParser*       parser = nil;
    
    @try {
        jsonResponse = [[NSString alloc] initWithData:data 
encoding:NSUTF8StringEncoding];    
        parser = [[SBJsonParser alloc] init];
        
        id jsonObject = [parser objectWithString:jsonResponse];
        NSDictionary* feature = [(NSArray*)[jsonObject 
objectForKey:@"features"] objectAtIndex:0];
        
        self.name = [[feature objectForKey:@"properties"] objectForKey:@"name"];
        
        if (jsonObject) {
            [self performSelectorOnMainThread:@selector(updateLabels) 
withObject:nil waitUntilDone:NO];
        }        
    }
    @catch (NSException * ex) {
        <snip>
    }
    @finally {
        [jsonResponse release]; 
        [parser release];        
        [pool release];        
    }    
}


- (void) updateLabels
{
    self.nameLabel.text = self.name;
}



One *important* observations is here:
Before generating the URL request, I actually need a parameter which is asked 
from the user via an interface.
When the user starts to edit the input (a UITextField) the view controller gets 
notified through a method, shown below.
The purpose of this method is to clear the previous results.

** IFF I do not set the text property to nil, the NSString instance "name" 
remains valid. So, it seems, that the string object will be *shared* - but not 
copied. Hence the auto release pool does not dealloc the string. The label's 
text property is declared as: @property(nonatomic, copy) NSString* text
This looks strange to me. Any thoughts?


- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    // User entered editing: clear labels:
    self.nameLabel = nil;  // if uncommented, the ivar "name" remains valid 
}

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to