Вопрос

i'm trying to make a subclass of NSURLConnection where i have an additional property (in this case "connectionName") to help me distinguish between 2 different connections.

i created the subclass, named it CustomURLConnection and gave it the property "connectionName".

then in my file ImagesViewController.m (which is an UICollectionView) i import the header CustomURLConnection and try to give the connections a name and retrieve it afterwards, but it doesn't work, as soon as i enter this collection view the app crashes and gives me the following error:

-[NSURLConnection setConnectionName:]: unrecognized selector sent to instance 0x1090a40f0

Here is some code: (if you want, here's a CLEARER IMAGE)

CustomURLConnection.h

#import <Foundation/Foundation.h>

@interface CustomURLConnection : NSURLConnection

@property (strong, nonatomic) NSString *connectionName;

@end

ImagesViewController.h

#import <UIKit/UIKit.h>

@interface ImagesViewController : UICollectionViewController<NSURLConnectionDelegate>

@property (strong, nonatomic) UIImageView *imageView;

@end

ImagesViewController.m

...
#import "CustomURLConnection.h"

@interface ImagesViewController (){
    NSArray *contentStrings;
    NSMutableData *contentData; // Holds data from the initial load
    NSMutableData *contentImageData; // Holds data when the user scrolls up/down in the collection view
}
@end

...

-(void)loadInitialData{ // Loads data from page
    NSString *hostStr = @"http://www.website.com/example";
    NSURL *dataURL = [NSURL URLWithString:hostStr];
    NSURLRequest *request = [NSURLRequest requestWithURL:dataURL];
    CustomURLConnection *connectionData = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self]; // Make connection
    connectionData.connectionName = @"InitialData"; // Give it a name
}

...

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    // Do some stuff

    NSString *hostStr = @"http://www.website.com/example2";

    _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,100,100)];
    [imageCell addSubview:_imageView]; // Adds an image view to each collection cell

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:hostStr]];
    CustomURLConnection *connectionImg = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self]; // Make connection
    connectionImg.connectionName = @"ImageData"; // Give it a different name than before

    // Do some stuff
    return imageCell;
}

...

// Here are the main methods for the connections
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    if([((CustomURLConnection *)connection).connectionName isEqualToString:@"InitialData"]){
        contentData = [[NSMutableData alloc] init];
    }
    else{
        contentImageData = [[NSMutableData alloc] init];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    if([((CustomURLConnection *)connection).connectionName isEqualToString:@"InitialData"]){
        [contentData appendData:data];
    }
    else{
        [contentImageData appendData:data];
    }
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    if([((CustomURLConnection *)connection).connectionName isEqualToString:@"InitialData"]){
        // Do some stuff
    }
    else{
        UIImage *image = [[UIImage alloc] initWithData:contentImageData];
        _imageView.image = image;
    }
}

am i missing something? i came across this error many times before but the causes are never the same and this time i can't seem to find a solution on my own.

hopefully you can see what i'm doing wrong and help me :) thanks.

EDIT: turns out there is a better way to achieve my goal, have a look here
Thank again to everyone for the help :)

Это было полезно?

Решение 2

In your delegate methods change NSURLConnection by CustomURLConnection, for instance :

- (void)connection:(CustomURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

and when you create it just do :

CustomURLConnection *connectionImg = [[CustomURLConnection alloc] initWithRequest:request delegate:self];
connectionImg.connectionName = @"ImageData"; // Give it a different name than before

Другие советы

CustomURLConnection *connectionImg = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self]; // Make connection

creates an NSURLConnection object. Casting to CustomURLConnection does not change the class of this object. Replace that line with

CustomURLConnection *connectionImg = [CustomURLConnection connectionWithRequest:request delegate:self]; // Make connection

to create an instance of your subclass.

In this line:

CustomURLConnection *connectionData = (CustomURLConnection *)[NSURLConnection connectionWithRequest:request delegate:self];

you are creating an instance of NSURLConnection, not CustomURLConnection. So, when you cast the result to CustomURLConnection * you are lying to the compiler.

Later, at runtime, when you try to use a feature of CustomURLConnection you get an exception because your connection is the wrong class type and doesn't implement the method.

You need to instantiate CustomURLConnection, not NSURLConnection.

Adding to the other good answers here, your CustomURLConnection class should override +connectionWithRequest:delegate: to return an instance of CustomURLConnection, like this:

+(CustomURLConnection*)connectionWithRequest:(NSURLRequest*)request delegate:(id)delegate
{
    return [[CustomURLConnection alloc] initWithRequest:request delegate:delegate];
}

That lets you use the same style you had:

CustomURLConnection *connectionData = [CustomURLConnection connectionWithRequest:request delegate:self]; // Make connection

More importantly, a user of your code (most likely the future you) might assume that sending +connectionWithRequest:delegate: to CustomURLConnection would return an instance of CustomURLConnection. Without the override, they'll get an instance of NSURLConnection instead, and that's a difficult bug to spot.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top