在开始之前,我想我应该让大家知道我是一个自学成才的初学者,没有正式背景。

我的目标:将来自www.3v3live.com的已解析HTML数据显示为我的应用程序中的各种 View 。

实现的总体计划:我将创建一个可重用的方法,可以调用该方法来分析站点的不同页面。它将具有三个参数,包括:URL,Xpath查询和数据类型(作为字符串输入并通过该方法转换为类)。该方法应以数组中的数据类型(来自第三个参数)返回收集的数据。

我的错误:1)“选择器'parseData:::'的未知类方法
2)“选择器'stringFromArray:没有已知的类方法”

我的输出:无

我尝试修复错误:1)我已将它们添加到.h文件和.m界面中
2)我已经添加了协议(protocol)(建议在此处给出答案)
3)我已经将方法转换为实例方法(并返回)
4)我已经清理并运行了项目

注意:错误发生在“textSet”方法中最底部的一行,“makeSlideShow”和“getText”方法是我的新方法出现错误的先兆(这些先驱也出错)。

我的代码(忽略评论):

(ViewController.h

#import <UIKit/UIKit.h>

@protocol dataParsingVC <NSObject>

+ (id) stringFromArray: (NSArray*) arr;
+ (id) parseData: (NSString*) urlS : (NSString*) path : (NSString*) typeOfDataToReturn;

@end


@interface ViewController : UIViewController <NSURLConnectionDataDelegate>

// Drop Down Menu Buttons
@property (weak, nonatomic) IBOutlet UIButton *scheduleButton;
@property (weak, nonatomic) IBOutlet UIButton *newsButton;
@property (weak, nonatomic) IBOutlet UIButton *photosButton;
@property (weak, nonatomic) IBOutlet UIButton *docsButton;
@property (weak, nonatomic) IBOutlet UIButton *stagesButton;
@property (weak, nonatomic) IBOutlet UIButton *faqsButton;
@property (weak, nonatomic) IBOutlet UIButton *resultsButton;
@property (weak, nonatomic) IBOutlet UIButton *contactButton;
@property (weak, nonatomic) IBOutlet UIButton *finderButton;

- (IBAction)menuButton:(UIBarButtonItem *)sender;// Menu Button Open & Close

// WV = Web View; use as few as possible
@property (weak, nonatomic) IBOutlet UIWebView *hostATournamentWV; // for the poll
// SV = scroll view
@property (weak, nonatomic) IBOutlet UIScrollView *menuSV;
@property (weak, nonatomic) IBOutlet UIScrollView *homeSideTabsSV;
// Slide Show Image View
@property (weak, nonatomic) IBOutlet UIImageView *ssIV;
// TV = text view
@property (weak, nonatomic) IBOutlet UITextView *skillLevelsTV;
@property (weak, nonatomic) IBOutlet UITextView *homeTV;
@property (weak, nonatomic) IBOutlet UITextView * rulesTV;
// CV = container view
@property (weak, nonatomic) IBOutlet UIView *sideTabsCV;
// Arrays
@property (weak,nonatomic) NSMutableArray * _ssImagesArray;
@property (weak,nonatomic) NSMutableArray * _textArray;
// Error handling
@property (strong, nonatomic) NSMutableData * _responseData; // got warning in .m when prop was weak


// parsing related methods
+ (id) parseData: (NSString*) urlS : (NSString*) path : (NSString*) typeOfDataToReturn;
+ (id) stringFromArray: (NSArray*) arr;

@end

ViewController.m
#import "ViewController.h"
#import "TFHpple.h"
#import "TFHppleElement.h"


@interface ViewController ()

+ (id) parseData:(NSString *)urlS :(NSString *)path :(NSString *)typeOfDataToReturn;
+ (id) stringFromArray:(NSArray *)arr;

@end

@implementation ViewController

@synthesize _responseData;

@synthesize menuSV;
@synthesize homeSideTabsSV;
@synthesize homeTV;
@synthesize ssIV;
@synthesize hostATournamentWV;
@synthesize rulesTV;
@synthesize skillLevelsTV;

@synthesize _ssImagesArray;
@synthesize _textArray;

@synthesize scheduleButton;
@synthesize newsButton;
@synthesize photosButton;
@synthesize docsButton;
@synthesize stagesButton;
@synthesize faqsButton;
@synthesize resultsButton;
@synthesize contactButton;
@synthesize finderButton;



- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (IBAction) menuButton:(UIBarButtonItem *)sender {// When Drop Down Menu is pressed

    //self.menuSV.contentSize = CGSizeMake(160, 160);  // Make it so Scroll View (contains buttons) can scroll

    if (self.homeSideTabsSV.hidden) // if buttons aren't showing, then uncover them
    {
      self.homeSideTabsSV.hidden = false;

    } else if (self.homeSideTabsSV.hidden == false) // else (they're showing) hide them
    {
      self.homeSideTabsSV.hidden = true;
    }
}


+ (id) stringFromArray : (NSArray *) arr // creates a string when given an array
{

    NSString * result = [arr description];
    return result;

}

+ (id) parseData: (NSString*) urlS : (NSString*) path : (NSString*) typeOfDataToReturn
{

    // Set up request
    NSURL * url = [NSURL URLWithString:urlS];
    NSURLRequest * request = [NSURLRequest requestWithURL:url];
    NSURLResponse * response = nil;
    NSError * error = nil;

    // Send request
    NSData * gatheredData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if (error) {return error;}
    // set up parser
    TFHpple * Parser = [TFHpple hppleWithHTMLData:gatheredData];

    // Parse data
    NSArray * Nodes = [Parser searchWithXPathQuery:path];

    // Set up array to be returned
    NSMutableArray * array = [[NSMutableArray alloc]initWithCapacity:0];

    // Insert parsed data into "array"
    for (TFHppleElement * element in Nodes)
    {
        // tell returned data it's class
        id dataType = NSClassFromString(typeOfDataToReturn);
        id returnedData = [[dataType alloc] init];
        // set returnedData's value and insert it into "array"
        returnedData= [[element firstChild] content];
        [array addObject:returnedData];
    }

    return array;
}

- (void) textSet // setText already exists, so this one is textSet
{
    // set homeTV's text = the string form (from "stringFromArray") of the array from "parseData"
    [self.homeTV setText:[NSString stringFromArray:[ NSArray parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]]];

}


// call method with url & path to get text
- (id) getText:(NSURL*) url :(NSString*) path
{

    NSData * gatheredText = [NSData dataWithContentsOfURL:url];
    TFHpple * textParser = [TFHpple hppleWithHTMLData: gatheredText];
    NSArray * textNodes = [textParser searchWithXPathQuery:path];
    NSMutableArray * textArray = [[NSMutableArray alloc]initWithCapacity:0];
    for (TFHppleElement * element in textNodes)
    {
        NSString * text = [[element firstChild] content]; // set text's value
       [textArray addObject:text]; // add text to textArray

    }

    int z = [_textArray count]; // set z = end of _textArray
    NSRange range = NSMakeRange(z, [textArray count]); // make a range from z to end of textArray
    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndexesInRange:range]; // make an indexSet from range
    [_textArray insertObjects:textArray atIndexes:indexSet]; // insert new parsed info at end of _textArray
    return textArray;
}


- (void) makeSlideShow { // gets images for Slide Show
    NSURLRequest * imagesURL = [NSURLRequest requestWithURL:[NSURL URLWithString: @"http://www.3v3live.com"]]; // request connection
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * gatheredImages = [NSURLConnection sendSynchronousRequest:imagesURL returningResponse:&response error:&error];// get raw data

    if (error == nil)
    {
        // Parse data here
        TFHpple *imageParser1 = [TFHpple hppleWithHTMLData:gatheredImages]; // parses for almost all images in slide show
        TFHpple *imageParser2 = [TFHpple hppleWithHTMLData:gatheredImages]; // parses for displayed image

        NSString * parsePath1 = @"//div[@class ='newsSlideShow-article']"; // not shown pics path
        NSString * parsePath2 = @"//div[@class = 'newsSlideShow-article current']"; // shown pic path

        NSArray * Nodes = [imageParser1 searchWithXPathQuery:parsePath1]; // not shown pics array
        NSArray * currentArticleArray = [imageParser2 searchWithXPathQuery:parsePath2]; // stores shown image

        UIImage * currentArticle = [currentArticleArray objectAtIndex:0]; // displayed image in slide show should be first in the above array
        [_ssImagesArray addObject:currentArticle ]; // add in displayed pic

        int x = 1;
        for (TFHppleElement * element in  Nodes)// seperate collected data into pics; inserts rest of pics into imagesArray
        {
            x++;
            UIImage * image = [UIImage imageWithData:[NSURL URLWithString:[element objectForKey:@"href"]]]; // set image's value
            [_ssImagesArray addObject:image]; // add it to imagesArray
        }
    }
};

int j = 1; // counter for loopSlideShow
- (void) loopSlideShow // runs the slide show with gathered images from createSlideShow
{
    int delayTime = 5; // how long each pic is shown
    while (self.ssIV) // while the slideShowPic exists
    {
        if (j == [_ssImagesArray count]) // if it's reached the last pic, loop back to beggining of Slide Show
        {
            j = 1;

        } else // else go on to next pic
        {
            j++;

        };
        [ssIV setImage:[_ssImagesArray objectAtIndex:j]]; // tell slide show which pic to display
        [self performSelector:@selector(loopSlideShow) withObject:self afterDelay:delayTime]; // show each picture for X seconds
    }
};

@end

最佳答案

看来-[ViewController parseData:::]实际上是ViewController的方法,因此如果您在NSArray上调用它就没有意义

如果将其保留为类方法,则应使用

[self.class parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]

或将其更改为实例方法并使用
[self parseData: @"http://www.3v3live.com" : @"//p" : @"NSString"]

无论哪种方式,这都是一个名称很差的方法,似乎缺少一些基本的面向对象的编程概念。苹果在启动Objective-C和iOS开发方面有一些非常好的资源。

关于ios - 弧语义问题: No known class method for selector (method name here),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25110000/

10-12 00:15
查看更多