2

我已经拔了两天多的头发来解决这个问题,我非常抗拒不在这里问问题,因为这可能是以前别人的问题,但是像这样在 Stackoverflow 上搜索和阅读所有相关问题,或者这个并阅读更多教程并测试不同的示例代码,我仍然无法弄清楚这一点。

我有一个 RSS 解析器应用程序,自从两年前在商店发布以来,它一直运行良好。这是一个简单的NSXMLParser实现,从那时起我在许多应用程序中都使用了它,如果需要,可以做一些小的改动。现在我在另一个项目上实现相同的代码,它仍然可以正常工作,但是当我关闭 wifi 或使用无效的 url 解析时,它不会在iPhone Simulatoror上抛出错误iPhone 5, iOS 7.0.3,而相同的代码在iPhone 4S, iOS 6.1.3

这是我的代码:

NIKFeedParser.h

#import <Foundation/Foundation.h>
#import "NIKFeedEntry.h"

@class NIKFeedEntry;
@protocol NIKFeedParserDelegate;


@interface NIKFeedParser : NSObject <NSXMLParserDelegate>
{
    NIKFeedEntry *currentItem;
    NSMutableString *currentItemValue;
NSMutableArray *feedItems;
id<NIKFeedParserDelegate> delegate;
NSOperationQueue *retrieverQueue;
NSUInteger parsingFeedsWithNumbers;
NSOperationQueue *queue;
}

@property (strong, nonatomic) NIKFeedEntry *currentItem;
@property (strong, nonatomic) NSMutableString *currentItemValue;
@property (readonly) NSMutableArray *feedItems;
@property (strong, nonatomic) id<NIKFeedParserDelegate> delegate;
@property (strong, nonatomic) NSOperationQueue *retrieverQueue;
@property (nonatomic) NSUInteger parsingFeedsWithNumbers;
@property (strong, nonatomic) NSOperationQueue *queue;

@property (nonatomic) NSString *selectedCategory;


- (void) startProcess;

@end

@protocol NIKFeedParserDelegate <NSObject>

- (void) processCompleted;
- (void) processHasErrors;

@end

NIKFeedParser.m

#import "NIKFeedParser.h"

@implementation NIKFeedParser

@synthesize currentItem;
@synthesize currentItemValue;
@synthesize feedItems;
@synthesize delegate;
@synthesize retrieverQueue;
@synthesize parsingFeedsWithNumbers;
@synthesize queue;
@synthesize selectedCategory;
- (id) init
{
    if (![super init])
    {
        return nil;
    }
    feedItems = [[NSMutableArray alloc] init];
    queue = [NSOperationQueue new];
    return self;
}

- (NSOperationQueue *)retrieverQueue
{
    if (nil == retrieverQueue)
    {
        retrieverQueue = [[NSOperationQueue alloc] init];
        retrieverQueue.maxConcurrentOperationCount = 1;
    }

    return retrieverQueue;
}

- (void) startProcess
{
    SEL method = @selector (fetchAndParseFeed);
    [[self feedItems] removeAllObjects];
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:method object:nil];

    [self.retrieverQueue addOperation:op];
}

- (BOOL)fetchAndParseFeed
{
    parsingFeedsWithNumbers = 0;
    @autoreleasepool {
        //NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

        //To suppress the leak in NSXMLParser.
        [[NSURLCache sharedURLCache] setMemoryCapacity:0];
        [[NSURLCache sharedURLCache] setDiskCapacity:0];
        NSString *file = [[NSBundle  mainBundle] pathForResource:@"Feed" ofType:@"plist"];
        NSDictionary *item = [[NSDictionary alloc]initWithContentsOfFile:file];
        NSArray *array = [item objectForKey:@"Root"];
        NSURL *url = [NSURL URLWithString:
                      [[array objectAtIndex:[selectedCategory intValue]]objectForKey:@"URL"]];
        BOOL success = NO;
        NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
        [parser setDelegate:self];
        [parser setShouldProcessNamespaces:YES];
        [parser setShouldReportNamespacePrefixes:YES];
        [parser setShouldResolveExternalEntities:NO];
        success = [parser parse];

        return success;
    }
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    if(nil != qualifiedName)
    {
        elementName = qualifiedName;
    }

    //NSLog(@"elementName: %@", elementName);

    if ([elementName isEqualToString:@"item"])
    {
        self.currentItem = [[NIKFeedEntry alloc] init];
        parsingFeedsWithNumbers++;
    }

    else if([elementName isEqualToString:@"title"] ||
            [elementName isEqualToString:@"description"] ||
            [elementName isEqualToString:@"link"] ||
            [elementName isEqualToString:@"guid"] ||
            [elementName isEqualToString:@"author"]||
            [elementName isEqualToString:@"pubDate"])
    {
        self.currentItemValue = [NSMutableString string];
    }

    else
    {
        self.currentItemValue = nil;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if(nil != self.currentItemValue){
        [self.currentItemValue appendString:string];
    }
}



- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if(nil != qName)
    {
        elementName = qName;
    }
    if([elementName isEqualToString:@"title"])
    {

        self.currentItem.podcastTitle = self.currentItemValue;
//        int titleLength = [self.currentItem.title length];
//        int len = (titleLength > 70) ? 70: titleLength;
//        self.currentItem.shortTitle = [self.currentItem.title substringWithRange:NSMakeRange(0, len)];


    }

    else if([elementName isEqualToString:@"link"])
    {
        self.currentItem.podcastURL = self.currentItemValue;
    }
    else if([elementName isEqualToString:@"guid"])
    {
//      self.currentItem.guidUrl = self.currentItemValue;
    }
    else if ([elementName isEqualToString:@"author"])
    {
//        self.currentItem.author = self.currentItemValue;
    }
    else if([elementName isEqualToString:@"pubDate"])
    {
//      self.currentItem.podcastDate = self.currentItemValue;
//        self.currentItem.pubDate = [FarsiNumbers convertNumbersToFarsi:self.currentItemValue];
    }
    else if([elementName isEqualToString:@"item"])
    {
        [[self feedItems] addObject:self.currentItem];
    }
}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{
    //CDATAblock implementation
}


- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
    NSLog(@"parseErrorOccurred");

    if(parseError.code != NSXMLParserDelegateAbortedParseError) {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        [(id)[self delegate] performSelectorOnMainThread:@selector(processHasErrors)
                                              withObject:nil
                                           waitUntilDone:NO];
    }
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"parserDidEndDocument");
    //TitleViewController *viewController = [[TitleViewController alloc] init];
    //viewController.parseFinished = @"1";
//    parseFinished = [[NSString  alloc] initWithFormat:@"%d", 1];

    // NSLog(@"rss parser parser finished, %@", viewController.parseFinished);
    parsingFeedsWithNumbers = 0;
    [(id)[self delegate] performSelectorOnMainThread:@selector(processCompleted)
                                          withObject:nil
                                       waitUntilDone:NO];

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}


@end

我的NIKMasterViewController.m

- (void)viewDidLoad
{
    feedParser = [[NIKFeedParser alloc] init];
    [[self feedParser] setSelectedCategory:[self selectedCategory]];
    [[self feedParser] setDelegate:self];
    [[self feedParser] startProcess];
}

- (void)processCompleted
{
    [[self tableView] reloadData];
    [activityIndicator stopAnimating];
    NSInteger rowCount = [[[self feedParser] feedItems] count];

    if (rowCount!=0) {
        //

        self.tableView.delegate = self;
        self.tableView.dataSource = self;
    }
    else if ((rowCount==0) &&([UIApplication sharedApplication].networkActivityIndicatorVisible == NO ) ){
        UILabel *noContentWarning = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 480, 480)];
        noContentWarning.text = NO_CONTENT_WARNING_MESSAGE;
        noContentWarning.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/3);
    }

}


- (void)processHasErrors
{
    //Due to internet connection or server error.
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NO_CONNECTION_ALERT_TITLE message: NO_CONNECTION_ALERT_MESSAGE delegate:self cancelButtonTitle:NO_CONNECTION_ALERT_VIEW_DISMISS_BUTTON otherButtonTitles:nil];
    [alert show];
    [activityIndicator stopAnimating];
}

在主要方法上设置断点并跟踪代码,这是调用方法的顺序:

  1. NIKFeedParser - init
  2. NIKMasterViewController - viewDidLoad
  3. NIKFeedParser - startProcess
  4. NIKFeedParser - retrieveQueue
  5. NIKFeedParser - startProcess - [self.retrieverQueue addOperation:op];
  6. NIKMasterViewController - viewDidLoad

然后我有银行表视图控制器,显然不是可见的网络指示器,因为 wifi 已关闭,而以前,它能够显示UIAlertView告诉我发生连接错误。Apple 在新的 iOS 或 SDK 中发生了哪些变化?或者我错过了什么?

4

0 回答 0