- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 UITableView,它在 Interface Builder 中设置并正确连接到 Xcode 中的类。我还有一个“Importer”类,它下载并解析 RSS 提要并将信息存储在 NSMutableArray 中。
但是我已经验证解析是否正常工作(使用断点和 NSlog),但 UITable View 中没有显示任何数据。关于问题可能是什么的任何想法吗?我快要摆脱他们了。
它基于 XML 性能 Apple 示例。
更新2:好的,在研究了以下信息后,我知道的是:
更新:好的,结果如下:
parserDidEndParsingData断点上的“po events”给了我“无法访问地址0x0处的内存”的答复。
po [self tableView] 显示 ">当前语言:自动;当前目标-c”
在节中行数下的断点中,我收到以下“()”消息。
我检查过的IB项目都如你所说。我怀疑由于上述错误而没有加载数组?
我还添加了解析代码,如果有帮助的话。
这是 TableView.h 的代码:
#import <UIKit/UIKit.h>
#import "IncidentsImporter.h"
@class SongDetailsController;
@interface CurrentIncidentsTableViewController : UITableViewController <IncidentsImporterDelegate>{
NSMutableArray *incidents;
SongDetailsController *detailController;
UITableView *ctableView;
IncidentsImporter *parser;
}
@property (nonatomic, retain) NSMutableArray *incidents;
@property (nonatomic, retain, readonly) SongDetailsController *detailController;
@property (nonatomic, retain) IncidentsImporter *parser;
@property (nonatomic, retain) IBOutlet UITableView *ctableView;
// Called by the ParserChoiceViewController based on the selected parser type.
- (void)beginParsing;
@end
.m 的代码:
#import "CurrentIncidentsTableViewController.h"
#import "SongDetailsController.h"
#import "Incident.h"
@implementation CurrentIncidentsTableViewController
@synthesize ctableView, incidents, parser, detailController;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.parser = [[IncidentsImporter alloc] init];
parser.delegate = self;
[parser start];
UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(beginParsing)];
self.navigationItem.rightBarButtonItem = refreshButton;
[refreshButton release];
// Uncomment the following line to preserve selection between presentations.
//self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewWillAppear:(BOOL)animated {
NSIndexPath *selectedRowIndexPath = [ctableView indexPathForSelectedRow];
if (selectedRowIndexPath != nil) {
[ctableView deselectRowAtIndexPath:selectedRowIndexPath animated:NO];
}
}
// This method will be called repeatedly - once each time the user choses to parse.
- (void)beginParsing {
NSLog(@"Parsing has begun");
//self.navigationItem.rightBarButtonItem.enabled = NO;
// Allocate the array for song storage, or empty the results of previous parses
if (incidents == nil) {
NSLog(@"Grabbing array");
self.incidents = [NSMutableArray array];
} else {
[incidents removeAllObjects];
[ctableView reloadData];
}
// Create the parser, set its delegate, and start it.
self.parser = [[IncidentsImporter alloc] init];
parser.delegate = self;
[parser start];
}
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
return YES;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [incidents count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Table Cell Sought");
static NSString *kCellIdentifier = @"MyCell";
UITableViewCell *cell = [ctableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease];
cell.textLabel.font = [UIFont boldSystemFontOfSize:14.0];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.text = @"Test";//[[incidents objectAtIndex:indexPath.row] title];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.detailController.incident = [incidents objectAtIndex:indexPath.row];
[self.navigationController pushViewController:self.detailController animated:YES];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)parserDidEndParsingData:(IncidentsImporter *)parser {
[ctableView reloadData];
self.navigationItem.rightBarButtonItem.enabled = YES;
self.parser = nil;
}
- (void)parser:(IncidentsImporter *)parser didParseIncidents:(NSArray *)parsedIncidents {
//[incidents addObjectsFromArray: parsedIncidents];
// Three scroll view properties are checked to keep the user interface smooth during parse. When new objects are delivered by the parser, the table view is reloaded to display them. If the table is reloaded while the user is scrolling, this can result in eratic behavior. dragging, tracking, and decelerating can be checked for this purpose. When the parser finishes, reloadData will be called in parserDidEndParsingData:, guaranteeing that all data will ultimately be displayed even if reloadData is not called in this method because of user interaction.
if (!ctableView.dragging && !ctableView.tracking && !ctableView.decelerating) {
self.title = [NSString stringWithFormat:NSLocalizedString(@"Top %d Songs", @"Top Songs format"), [parsedIncidents count]];
[ctableView reloadData];
}
}
- (void)parser:(IncidentsImporter *)parser didFailWithError:(NSError *)error {
// handle errors as appropriate to your application...
}
- (void)dealloc {
[super dealloc];
}
@end
这是 parser.h 的代码:
#import <UIKit/UIKit.h>
#import <libxml/tree.h>
@class IncidentsImporter, Incident;
// Protocol for the parser to communicate with its delegate.
@protocol IncidentsImporterDelegate <NSObject>
@optional
// Called by the parser when parsing is finished.
- (void)parserDidEndParsingData:(IncidentsImporter *)parser;
// Called by the parser in the case of an error.
- (void)parser:(IncidentsImporter *)parser didFailWithError:(NSError *)error;
// Called by the parser when one or more songs have been parsed. This method may be called multiple times.
- (void)parser:(IncidentsImporter *)parser didParseIncidents:(NSArray *)parsedIncidents;
@end
// This approach to parsing uses NSURLConnection to asychronously retrieve the XML data. libxml's SAX parsing supports chunked parsing, with no requirement for the chunks to be discrete blocks of well formed XML. The primary purpose of this class is to start the download, configure the parser with a set of C callback functions, and pass downloaded data to it. In addition, the class maintains a number of state variables for the parsing.
@interface IncidentsImporter : NSObject {
@private
id <IncidentsImporterDelegate> delegate;
// Reference to the libxml parser context
xmlParserCtxtPtr context;
NSURLConnection *rssConnection;
NSMutableArray *parsedIncidents;
// Overall state of the parser, used to exit the run loop.
BOOL done;
// State variable used to determine whether or not to ignore a given XML element
BOOL parsingAIncident;
// The following state variables deal with getting character data from XML elements. This is a potentially expensive
// operation. The character data in a given element may be delivered over the course of multiple callbacks, so that
// data must be appended to a buffer. The optimal way of doing this is to use a C string buffer that grows exponentially.
// When all the characters have been delivered, an NSString is constructed and the buffer is reset.
BOOL storingCharacters;
NSMutableData *characterBuffer;
// A reference to the current song the parser is working with.
Incident *currentIncident;
// The number of parsed songs is tracked so that the autorelease pool for the parsing thread can be periodically
// emptied to keep the memory footprint under control.
NSUInteger countOfParsedIncidents;
NSAutoreleasePool *downloadAndParsePool;
NSDateFormatter *parseFormatter;
}
@property (nonatomic, assign) id <IncidentsImporterDelegate> delegate;
@property (nonatomic, retain) NSMutableArray *parsedIncidents;
@property BOOL storingCharacters;
@property (nonatomic, retain) NSMutableData *characterBuffer;
@property BOOL done;
@property BOOL parsingAIncident;
@property NSUInteger countOfParsedIncidents;
@property (nonatomic, retain) Incident *currentIncident;
@property (nonatomic, retain) NSURLConnection *rssConnection;
@property (nonatomic, retain) NSDateFormatter *parseFormatter;
// The autorelease pool property is assign because autorelease pools cannot be retained.
@property (nonatomic, assign) NSAutoreleasePool *downloadAndParsePool;
- (void)downloadAndParse:(NSURL *)url;
- (void)finishedCurrentIncident;
- (void)start;
- (void)downloadStarted;
- (void)downloadEnded;
- (void)parseEnded;
- (void)parsedIncident:(Incident *)incident;
- (void)parseError:(NSError *)error;
- (void)addToParseDuration:(NSNumber *)duration;
@end
和parser.m:
#import "IncidentsImporter.h"
#import "Incident.h"
#import <libxml/tree.h>
static NSUInteger kCountForNotification = 10;
// Function prototypes for SAX callbacks. This sample implements a minimal subset of SAX callbacks.
// Depending on your application's needs, you might want to implement more callbacks.
static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes);
static void endElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI);
static void charactersFoundSAX(void * ctx, const xmlChar * ch, int len);
static void errorEncounteredSAX(void * ctx, const char * msg, ...);
// Forward reference. The structure is defined in full at the end of the file.
static xmlSAXHandler simpleSAXHandlerStruct;
@implementation IncidentsImporter
@synthesize delegate, rssConnection, done, parsingAIncident, parsedIncidents, storingCharacters, currentIncident, countOfParsedIncidents, characterBuffer, parseFormatter, downloadAndParsePool;
- (void)start {
NSLog(@"URL Gained");
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSURL *url = [NSURL URLWithString:@"http://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStore.woa/wpa/MRSS/newreleases/limit=300/rss.xml"];
[NSThread detachNewThreadSelector:@selector(downloadAndParse:) toTarget:self withObject:url];
}
- (void)downloadStarted {
NSLog(@"Download has begun");
NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__);
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
- (void)downloadEnded {
NSLog(@"Download has ended");
NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)parseEnded {
NSLog(@"Parsing has ended");
NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__);
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parser:didParseIncidents:)] && [parsedIncidents count] > 0) {
[self.delegate parser:self didParseIncidents:parsedIncidents];
}
[self.parsedIncidents removeAllObjects];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parserDidEndParsingData:)]) {
[self.delegate parserDidEndParsingData:self];
}
}
- (void)parsedIncident:(Incident *)incident {
NSLog(@"Parsing has begun on thread");
NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__);
[self.parsedIncidents addObject:incident];
if (self.parsedIncidents.count > kCountForNotification) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parser:didParseIncidents:)]) {
[self.delegate parser:self didParseIncidents:parsedIncidents];
}
[self.parsedIncidents removeAllObjects];
}
}
- (void)parseError:(NSError *)error {
NSLog(@"Parsing has an error");
NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__);
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(parser:didFailWithError:)]) {
[self.delegate parser:self didFailWithError:error];
}
}
- (void)addToParseDuration:(NSNumber *)duration {
NSAssert2([NSThread isMainThread], @"%s at line %d called on secondary thread", __FUNCTION__, __LINE__);
}
/*
This method is called on a secondary thread by the superclass. We have asynchronous work to do here with downloading and parsing data, so we will need a run loop to prevent the thread from exiting before we are finished.
*/
- (void)downloadAndParse:(NSURL *)url {
NSLog(@"Downloading and Parsing");
self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
done = NO;
self.parseFormatter = [[[NSDateFormatter alloc] init] autorelease];
[parseFormatter setDateStyle:NSDateFormatterLongStyle];
[parseFormatter setTimeStyle:NSDateFormatterNoStyle];
// necessary because iTunes RSS feed is not localized, so if the device region has been set to other than US
// the date formatter must be set to US locale in order to parse the dates
[parseFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"AU"] autorelease]];
self.characterBuffer = [NSMutableData data];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url];
// create the connection with the request and start loading the data
rssConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
// This creates a context for "push" parsing in which chunks of data that are not "well balanced" can be passed
// to the context for streaming parsing. The handler structure defined above will be used for all the parsing.
// The second argument, self, will be passed as user data to each of the SAX handlers. The last three arguments
// are left blank to avoid creating a tree in memory.
context = xmlCreatePushParserCtxt(&simpleSAXHandlerStruct, self, NULL, 0, NULL);
[self performSelectorOnMainThread:@selector(downloadStarted) withObject:nil waitUntilDone:NO];
if (rssConnection != nil) {
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);
}
// Release resources used only in this thread.
xmlFreeParserCtxt(context);
self.characterBuffer = nil;
self.parseFormatter = nil;
self.rssConnection = nil;
self.currentIncident = nil;
[downloadAndParsePool release];
self.downloadAndParsePool = nil;
}
#pragma mark NSURLConnection Delegate methods
/*
Disable caching so that each time we run this app we are starting with a clean slate. You may not want to do this in your application.
*/
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
// Forward errors to the delegate.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
done = YES;
[self performSelectorOnMainThread:@selector(parseError:) withObject:error waitUntilDone:NO];
}
// Called when a chunk of data has been downloaded.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"Did receive data");
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
// Process the downloaded chunk of data.
xmlParseChunk(context, (const char *)[data bytes], [data length], 0);
NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start;
[self performSelectorOnMainThread:@selector(addToParseDuration:) withObject:[NSNumber numberWithDouble:duration] waitUntilDone:NO];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"Connection done loading");
[self performSelectorOnMainThread:@selector(downloadEnded) withObject:nil waitUntilDone:NO];
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
// Signal the context that parsing is complete by passing "1" as the last parameter.
xmlParseChunk(context, NULL, 0, 1);
NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start;
[self performSelectorOnMainThread:@selector(addToParseDuration:) withObject:[NSNumber numberWithDouble:duration] waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(parseEnded) withObject:nil waitUntilDone:NO];
// Set the condition which ends the run loop.
done = YES;
}
#pragma mark Parsing support methods
static const NSUInteger kAutoreleasePoolPurgeFrequency = 20;
- (void)finishedCurrentIncident {
[self performSelectorOnMainThread:@selector(parsedIncident:) withObject:currentIncident waitUntilDone:NO];
// performSelectorOnMainThread: will retain the object until the selector has been performed
// setting the local reference to nil ensures that the local reference will be released
self.currentIncident = nil;
countOfParsedIncidents++;
// Periodically purge the autorelease pool. The frequency of this action may need to be tuned according to the
// size of the objects being parsed. The goal is to keep the autorelease pool from growing too large, but
// taking this action too frequently would be wasteful and reduce performance.
if (countOfParsedIncidents == kAutoreleasePoolPurgeFrequency) {
[downloadAndParsePool release];
self.downloadAndParsePool = [[NSAutoreleasePool alloc] init];
countOfParsedIncidents = 0;
}
}
/*
Character data is appended to a buffer until the current element ends.
*/
- (void)appendCharacters:(const char *)charactersFound length:(NSInteger)length {
[characterBuffer appendBytes:charactersFound length:length];
}
- (NSString *)currentString {
// Create a string with the character data using UTF-8 encoding. UTF-8 is the default XML data encoding.
NSString *currentString = [[[NSString alloc] initWithData:characterBuffer encoding:NSUTF8StringEncoding] autorelease];
[characterBuffer setLength:0];
return currentString;
}
@end
#pragma mark SAX Parsing Callbacks
// The following constants are the XML element names and their string lengths for parsing comparison.
// The lengths include the null terminator, to ensure exact matches.
static const char *kName_Item = "item";
static const NSUInteger kLength_Item = 5;
static const char *kName_Title = "title";
static const NSUInteger kLength_Title = 6;
static const char *kName_Category = "link";
static const NSUInteger kLength_Category = 9;
static const char *kName_Itms = "itms";
static const NSUInteger kLength_Itms = 5;
static const char *kName_Artist = "description";
static const NSUInteger kLength_Artist = 7;
static const char *kName_Album = "guid";
static const NSUInteger kLength_Album = 6;
static const char *kName_ReleaseDate = "pubDate";
static const NSUInteger kLength_ReleaseDate = 12;
/*
This callback is invoked when the parser finds the beginning of a node in the XML. For this application,
out parsing needs are relatively modest - we need only match the node name. An "item" node is a record of
data about a song. In that case we create a new Song object. The other nodes of interest are several of the
child nodes of the Song currently being parsed. For those nodes we want to accumulate the character data
in a buffer. Some of the child nodes use a namespace prefix.
*/
static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes) {
IncidentsImporter *parser = (IncidentsImporter *)ctx;
// The second parameter to strncmp is the name of the element, which we known from the XML schema of the feed.
// The third parameter to strncmp is the number of characters in the element name, plus 1 for the null terminator.
if (prefix == NULL && !strncmp((const char *)localname, kName_Item, kLength_Item)) {
NSLog(@"Found node");
Incident *newIncident = [[Incident alloc] init];
parser.currentIncident = newIncident;
[newIncident release];
parser.parsingAIncident = YES;
} else if (parser.parsingAIncident && ( (prefix == NULL && (!strncmp((const char *)localname, kName_Title, kLength_Title) || !strncmp((const char *)localname, kName_Category, kLength_Category))) || ((prefix != NULL && !strncmp((const char *)prefix, kName_Itms, kLength_Itms)) && (!strncmp((const char *)localname, kName_Artist, kLength_Artist) || !strncmp((const char *)localname, kName_Album, kLength_Album) || !strncmp((const char *)localname, kName_ReleaseDate, kLength_ReleaseDate))) )) {
parser.storingCharacters = YES;
}
}
/*
This callback is invoked when the parse reaches the end of a node. At that point we finish processing that node,
if it is of interest to us. For "item" nodes, that means we have completed parsing a Song object. We pass the song
to a method in the superclass which will eventually deliver it to the delegate. For the other nodes we
care about, this means we have all the character data. The next step is to create an NSString using the buffer
contents and store that with the current Song object.
*/
static void endElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI) {
IncidentsImporter *parser = (IncidentsImporter *)ctx;
if (parser.parsingAIncident == NO) return;
if (prefix == NULL) {
if (!strncmp((const char *)localname, kName_Item, kLength_Item)) {
[parser finishedCurrentIncident];
parser.parsingAIncident = NO;
} else if (!strncmp((const char *)localname, kName_Title, kLength_Title)) {
NSLog(@"Parsing title");
parser.currentIncident.title = [parser currentString];
} else if (!strncmp((const char *)localname, kName_Category, kLength_Category)) {
NSLog(@"Parsing url");
parser.currentIncident.link = [NSURL URLWithString: [parser currentString]];
}
else if (!strncmp((const char *)localname, kName_Artist, kLength_Artist)) {
NSLog(@"Parsing description");
parser.currentIncident.description = [parser currentString];
} else if (!strncmp((const char *)localname, kName_Album, kLength_Album)) {
NSLog(@"Parsing guid");
parser.currentIncident.guid = [parser currentString];
} else if (!strncmp((const char *)localname, kName_ReleaseDate, kLength_ReleaseDate)) {
NSLog(@"Parsing date");
NSString *dateString = [parser currentString];
parser.currentIncident.pubDate = [parser.parseFormatter dateFromString:dateString];
}
}
parser.storingCharacters = NO;
}
/*
This callback is invo
最佳答案
将该行注释掉后,您如何获取这些事件?
- (void)parser:(IncidentsImporter *)parser didParseIncidents:(NSArray *)parsedIncidents {
//[incidents addObjectsFromArray: parsedIncidents];
当事件没有改变时调用 reloadData 并不会真正执行任何操作。
在同一函数中,仅当表静止时才调用 reloadData。如果您不调用它,则应设置一个标志,以便在表静止后调用 reloadData。有一些 UIScrollView 委托(delegate)回调可以检测到这一点。
关于iphone - UITableView 不显示解析的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2582686/
我坚持我的项目(用 Swift 编写) 我有一个 UITableView,它有一个字符串,它提供了表格中的十个类别。我想做的是选择这些类别中的一个来触摸它,然后打开一个包含其他类别的 secondTa
好的,这从 iOS 7 Beta 6 开始就被打破了。 在启动时,我将表格 View 的背景更改为图像(如果我将其设置为颜色,它会做同样的事情)并且表格单元格是白色的...... 当我选择一个单元格时
我有一个包含不同部分的 UITableView,每个单元格上都有一个图像。因为图像是为每个单元格单独下载的,所以我正在寻找一种延迟加载解决方案。 在 iOS Developer Library 上,它
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
可以在UIRefreshControl的底部添加UITableView吗? 我会用它来加载更多数据。 拜托,有什么建议吗? 最佳答案 我相信不会有任何简单的解决方案来解决这个问题。可能有人可以编写一个
我有一个 UITableView 和一个使用 Swift 的自定义 UITableViewCell。当我设置 self.MyTable.editing = true 时,我看到该行上有删除图标,并且似
我为 iPhone 创建了一个下载器应用程序。我有用于显示主动/被动下载的表格 View 。在 tableview 的自定义单元格中有进度条,它显示 %XX 下载状态。现在我正在使用 NSTimer
我正在编写 UITableView 的自定义子类。我需要这个对象本身成为它自己的数据源和委托(delegate),然后这个子类将有它自己的数据源和委托(delegate)。这主要是为了让我可以拦截对数
我有一个问题已经困扰我几天了。 我有一个名为 countries 的数组。该数组包含一个自定义对象,其中包含国家、城市、IP、状态等数据。 我需要在按属性“国家/地区”划分的表格 View 中显示这些
我有一个 UITableViewController,目前显示 4 个将始终显示的单元格,并且想将它们组合在一起,但我不知道如何操作。当在 UIViewController 或类似的东西上插入标准 U
我以编程方式创建了一个 UITableView,现在我想向它添加一个固定的标题。 正如我下面的代码一样,标题也随着我的 tableview 滚动。 UILabel *label = [[[UI
我正在创建一个 UITableViewController(在 UINavigationController 的根部)并在另一个 View Controller 之上以模态方式呈现它。我让它在一定程度
我有问题。我有动态 TableView 。所以我需要在我的 textLabel 中更改文本大小。我试过: 一个: cell.textLabel.font = [UIFont systemFontOfS
iOS 8 中的新功能是 separatorEffect属性,您可以为其分配 UIVisualEffect。有没有人知道这是做什么用的?我试过了,我不认为它有任何,呃,视觉效果。 最佳答案 我想知道完
今天早上,我刚刚安装了包含iOS 6的新Xcode。 我有一个加载了包含章节和行的plist文件的表格 View 。各章定义各节。 用户选择章节和行,并将tableview自动滚动到正确的位置(在vi
我在iOS 7上启动VoiceOver时遇到了一些麻烦。我确实在UITableViewHeaderFooterView中注册了viewDidLoad子类的实例,但是当我用-[tableView deq
我在 UITableView 中添加了一些数据,我想更改单元格中显示的文本的颜色。 是否有委托(delegate)方法可以执行此操作,或者有其他方式吗? 最佳答案 无需标签 您只需要编码: cell.
是否可以在滚动 UITableView 时动态更改单元格的高度? 当用户将其向下拖动到顶部时,滚动位置到达某个点时,我需要更改多个单元格的高度。我可以通过发出 reloadData 成功地做到这一点,
我正在使用 iOS 5,并在表格中动态生成单元格(2 个部分,每个部分 3 行)。每个部分都有一个标题,该标题也是使用 titleForHeaderInSection 调用动态生成的。 我还设置了一个
我正在寻找 UITableView 的回调函数当我使用 Apple Remote 导航并按向上或向下键选择行时(而不是按 Enter 键时),当该行聚焦时。 在 iOS 上,我们有 didSelect
我是一名优秀的程序员,十分优秀!