Select to view content in your preferred language

Updated to 2.2.1 Bad Access

702
3
06-01-2012 12:54 PM
brettlamy
New Contributor
I have my own custom tiledLayer and operation.
Which looks something like this

/////////////////////////////////////////////////////////////////////////////////////
- (NSOperation<AGSTileOperation>*) retrieveImageAsyncForTile:(AGSTile *) tile{
//Create an operation to fetch tile from local cache
S3TileOperation *operation;

if ([self.urlPath length]) {
operation = [[S3TileOperation alloc] initWithTile:tile
urlPath:self.urlPath
fileFormat:self.fileFormat
target:self 
action:@selector(didFinishOperation:)];
} else {
operation = [[S3TileOperation alloc] initWithTile:tile
tileDirectoryPath:self.tileDirectoryPath
fileFormat:self.fileFormat
target:self
action:@selector(didFinishOperation:)];
}

//Add the operation to the queue for execution
[super.operationQueue addOperation:operation];
return [operation autorelease];
}

/////////////////////////////////////////////////////////////////////////////////////
- (void) didFinishOperation:(NSOperation<AGSTileOperation>*)op {
DebugLog(@"didFinishOperation");

//If tile was found ...
if (op.tile.image != nil) {
// Notify tileDelegate of success
[self.tileDelegate tiledLayer:self operationDidGetTile:op];
} else {
// Notify tileDelegate of failure
[self.tileDelegate tiledLayer:self operationDidFailToGetTile:op];
}
}


retrieveImageAsyncForTile Creates a NSOperation which goes and fetches the tile. When the operation finishes I simply call:
[self.target performSelector:self.action withObject:self];
From inside of the NSOperation.

This calles to didFinishOperation in the code above. Everything works fine until I get to:
[self.tileDelegate tiledLayer:self operationDidGetTile:op];

Where the app crashes with a bad access with the following backtrace





The regression occurred when upgrading from 2.0.1 to 2.2.1.
0 Kudos
3 Replies
NimeshJarecha
Esri Regular Contributor
If possible, please upload your custom tiled layer code so I can have a look at and test it.

Regards,
Nimesh
0 Kudos
BrettBe
Emerging Contributor
If possible, please upload your custom tiled layer code so I can have a look at and test it.

Regards,
Nimesh


/////////////////////////////////////////////////////////////////////////////////////
- (id)initWithUrlPath:(NSString *)path fileFormat:(NSString *)format {
 
 if ((self = [super init])) {
  self.urlPath = path;
        self.fileFormat = format;
        
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/MapServer", self.urlPath]];
        
        // Clear old request if needed
        if (self.request != nil) {
            [self.request clearDelegatesAndCancel];
            self.request = nil;
        }
        
        // Create request
        ASIHTTPRequest* request = [[ASIHTTPRequest alloc] initWithURL:url];
        self.request = request;
        [request release];

        // Configure and start request
        [self.request setDelegate:self];
        [self.request startAsynchronous];
        
    }
    return self;
}

/////////////////////////////////////////////////////////////////////////////////////
- (id)initWithDirectortyPath:(NSString *)directoryPath tileDirectoryPath:(NSString*)tileDirectoryPath fileFormat:(NSString *)format {
    if ((self = [super init])) {
  self.directoryPath = directoryPath;
        self.tileDirectoryPath = tileDirectoryPath;
        self.fileFormat = format;
        
        NSString* filePath = [self.directoryPath stringByAppendingPathComponent:@"MapServer"];
        NSError *error;
        NSString* tmp = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
        self.json = tmp;
        [tmp release];
        
        [(NSObject*)self performSelector:@selector(parseJson) withObject:nil afterDelay:0.1];         
    }
    return self;
}


/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Private
/////////////////////////////////////////////////////////////////////////////////////
-(AGSSpatialReference *)spatialReference 
{
 return self.fullEnvelope.spatialReference;
}

/////////////////////////////////////////////////////////////////////////////////////
- (void)parseJson {
    
    DebugLog(@"parseJson%@", self.json);
    if (!self.json)
        return;
    NSDictionary* dict = [self.json JSONValue];
    
    AGSEnvelope* fullEnvelope = [[AGSEnvelope alloc] initWithJSON:[dict objectForKey:@"fullExtent"]];
    self.fullEnvelope = fullEnvelope;
    [fullEnvelope release];
    
    // Assume our initial extent is the same as the full extent
    AGSEnvelope* initialEnvelope = [[AGSEnvelope alloc] initWithJSON:[dict objectForKey:@"fullExtent"]];
    self.initialEnvelope = initialEnvelope;
    [initialEnvelope release];
    
    AGSTileInfo* tileInfo = [[AGSTileInfo alloc] initWithJSON:[dict objectForKey:@"tileInfo"]];
    self.tileInfo = tileInfo;
    [tileInfo release];
    
    self.units = AGSUnitsFromString([dict objectForKey:@"units"]);
    
    [self.tileInfo computeTileBounds:self.fullEnvelope];
    
    [self layerDidLoad];
    DebugLog(@"parseJson done");

}


/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark ASIHTTPRequestDelegate
/////////////////////////////////////////////////////////////////////////////////////
- (void)requestFinished:(ASIHTTPRequest *)request {
    self.json = [request responseString];
    [self.request setDelegate:nil];
    self.request = nil;
    [(NSObject*)self performSelector:@selector(parseJson) withObject:nil afterDelay:0.1];
}

/////////////////////////////////////////////////////////////////////////////////////
- (void)requestFailed:(ASIHTTPRequest *)request {
    NSError *error = [request error];  
    [self.request setDelegate:nil];
    self.request = nil;
    [self layerDidFailToLoad:error];
}


/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark AGSTiledLayer
/////////////////////////////////////////////////////////////////////////////////////
- (NSOperation<AGSTileOperation>*) retrieveImageAsyncForTile:(AGSTile *) tile{

 //Create an operation to fetch tile from local cache
    S3TileOperation *operation;
    
    if ([self.urlPath length]) {
        operation = [[S3TileOperation alloc] initWithTile:tile
                                                  urlPath:self.urlPath
                                               fileFormat:self.fileFormat
                                                   target:self 
                                                   action:@selector(didFinishOperation:)];
    } else {
        operation = [[S3TileOperation alloc] initWithTile:tile
                                        tileDirectoryPath:self.tileDirectoryPath
                                               fileFormat:self.fileFormat
                                                   target:self
                                                   action:@selector(didFinishOperation:)];
    }
    
    //Add the operation to the queue for execution
    [super.operationQueue addOperation:operation];
    return [operation autorelease];
}

/////////////////////////////////////////////////////////////////////////////////////
- (void) didFinishOperation:(NSOperation<AGSTileOperation>*)op {
    //DebugLog(@"didFinishOperation");
    
 //If tile was found ...
 if (op.tile.image != nil) {
  // Notify tileDelegate of success
        [self.tileDelegate tiledLayer:self operationDidGetTile:op];
 } else {
  // Notify tileDelegate of failure
  [self.tileDelegate tiledLayer:self operationDidFailToGetTile:op];
 }
}

@end
0 Kudos
NimeshJarecha
Esri Regular Contributor
Brett,

Code looks correct but it's hard to tell what is going wrong. Please upload a sample application which i can run and test it.

Thank you!

Regards,
Nimesh
0 Kudos