我有点菜鸟,所以希望它不太复杂。到目前为止,我的代码存在问题,使我和其他一些用户感到困惑和困惑。我花了一些时间清理我的代码,并遵循了一些教程,但是仍然可以克服这个问题。我只知道这确实很简单,所以去吧:
我为自己的博客网站制作了一个iOS应用。它转到该站点,提取一个XML文档(包含博客标题,简短描述和完整的文章URL),并将其解析以显示在UITableView中。为了管理此问题,有两个自定义对象:“ PostList”和“ Post”。 Post只是一个对象,用于保存各个帖子数据(URL,标题,发布日期等),而PostList具有一个数组,用于保存Post对象以及一些getter / setter / init函数。
一切都很好。视图加载并且XML被解析并显示在列表中。当用户点击链接或在屏幕上滚动某些单元时,就会出现问题。据我所知,这些都与同一个问题有关。在用户轻敲单元格的情况下,视图控制器不会将值传递给详细视图控制器(prepareForSegue),而在滚动情况下,cellForRowAtIndexPath不会重新初始化单元格值。
我相信这是由于相同的问题所致,一旦视图初始化,PostList数组中的现有值就会以某种方式删除。调试器说该数组仍然可以看到其内部的对象,但是它们都是空白对象。我花了很多时间试图找出原因。
如果您能给我一些想法,为什么会这样,那将是惊人的!我的代码如下。我发布了几乎所有内容,因为Ive之前没有发布足够的问题。希望这可以帮助。如果您需要更多,请询问!
-提前致谢 ;)
FirstViewController.h
#import <UIKit/UIKit.h>
#import "PostList.h"
#import "Post.h"
@interface FirstViewController : UITableViewController
@property (nonatomic, strong) PostList *postController;
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@property (nonatomic, strong) Post *postToSendToDetailView;
@property (nonatomic, strong) NSString *type;
@end
FirstViewController.m
#import "FirstViewController.h"
#import "DetailViewController.h"
#import "Post.h"
#import "PostList.h"
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.type = @"blog";
self.postController = [[PostList alloc] initWithType:self.type];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.postController countOfList];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Post *postAtSighting = [self.postController objectInListAtIndex:indexPath.row];
// Configure the cell...
[[cell textLabel] setText:postAtSighting.name];
[[cell detailTextLabel] setText:postAtSighting.content];
NSLog(@"Cell Initalized");
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"pushToDetailView"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *destViewController = segue.destinationViewController;
destViewController.aPost = [self.postController objectInListAtIndex:indexPath.row];
}
}
@end
PostList.h
#import <Foundation/Foundation.h>
#import "Post.h"
@interface PostList : NSObject
-(NSMutableArray *) getPostsofType:(NSString *)type;
-(NSString *) getName: (Post *)aPost;
-(NSUInteger) countOfList;
-(Post *)objectInListAtIndex:(NSUInteger)theIndex;
-(id)initWithType:(NSString *)type;
@property (nonatomic, strong) NSMutableArray *postsArray;
@property (nonatomic) NSString *urlString;
@property (nonatomic) NSUInteger countingIndex;
@end
PostList.m
#import "PostList.h"
#import "TBXML+HTTP.h"
@implementation PostList
- (id)initWithType:(NSString *)type {
self = [super init];
if (self) {
//Creates postArray to store Post objects
self.postsArray = [[NSMutableArray alloc] init];
//Create other resources
self.urlString = [[NSString alloc] init];
self.countingIndex = 0;
[self getPostsofType:type];
}
return self;
}
-(NSString *)getName:(Post *)somePost {
//Gets the Name of the Post object and returns the value
NSString *name = somePost.name;
return name;
}
-(NSMutableArray *)getPostsofType:(NSString *)type {
//Go to the Server and get the posts that are available for the post type selected.
//Determing the post type
if ([type isEqual: @"blog"]) {
self.urlString = @"http://www.biteofanapple.com/blog/feeds/blogFeed.xml";
}
if ([type isEqual: @"bbp"]) {
self.urlString = @"http://www.biteofanapple.com/blog/feeds/blogFeed.xml";
}
//Checks for an existant xmlBlogData.xml
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory
NSString* blogXML = [documentsDirectory stringByAppendingPathComponent:@"xmlBlogData.xml"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:blogXML];
NSData *data = [[NSData alloc] init];
//Determines the best way to handle the xml file
if (fileExists) {
data = [NSData dataWithContentsOfFile:blogXML];
} else {
NSURL *url = [NSURL URLWithString:self.urlString];
//Goes to the Server and reads the XML file of the Posts
data = [NSData dataWithContentsOfURL:url];
if (data != nil) {
NSLog(@" NSData value is not nil");
}
//Saves the XML data to a .dat file in the document's directory
NSError *error;
BOOL succeed = [data writeToFile:[documentsDirectory stringByAppendingPathComponent:@"xmlBlogData.dat"] atomically:YES];
if (!succeed){
// Handle error here
NSLog(@"Error: File was unable to be written to the documents directory.");
[error setValue:@"-1" forKey: @"File unable to be written"];
}
}
//Parses the XML file
TBXML *tbxml = [TBXML newTBXMLWithXMLData:data error:nil];
//Prints the data Variable to NSLog
NSLog(@"%@", [NSString stringWithUTF8String:[data bytes]]);
//Make some placeholder variables
if (tbxml.rootXMLElement == nil) {
NSLog(@"XML Document does not have rootElement. Error -1");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorry, there was an error" message:@"Could not find root XML element. Please contact support for help with this issue." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}
TBXMLElement *element = tbxml.rootXMLElement;
TBXMLElement *nextElement = element->nextSibling;
NSLog(@"URLs have been set, preparing for parse/input. [PostList.getPosts]");
//Extracts the content of the XML file and saves it to values in the Post Class
do {
/**********
* This loop goes through the XML file looking for <item> tags that hold information
* about the blog posts. It finds <item> tags and scours them for <title>, <description>,
* <pubdate>, and <link> tags to put into the class variables for the Post Class (aPost).
**********/
NSString *stringElement = [TBXML elementName:element];
NSLog(@"%@", stringElement);
//Creates Post variable to put stuff in.
Post *aPost = [[Post alloc] init];
//Sorts through the header junk to find the first <item> tag.
if (![stringElement isEqualToString:@"item"]) {
if (!(element->firstChild)) {
if (!(element->nextSibling)) {
element = nil;
}
element = element->nextSibling;
}
element = element->firstChild;
}
//Once the first <item> tag is found, this code executes.
else {
//Now we move to the first child tag and scour its contents and its siblings
nextElement = [TBXML nextSiblingNamed:@"item" searchFromElement:element];
element = element->firstChild;
do {
//Here it loops over and over until all the parts have been collected.
stringElement = [TBXML elementName:element];
if ([stringElement isEqualToString:@"title"]) {
aPost.name = [TBXML textForElement:element];
}
if ([stringElement isEqualToString:@"description"]) {
aPost.content = [TBXML textForElement:element];
}
if ([stringElement isEqualToString:@"link"]) {
aPost.postURL = [TBXML textForElement:element];
}
if ([stringElement isEqualToString:@"pubdate"]) {
aPost.publicationDate = [TBXML textForElement:element];
}
element = element->nextSibling;
} while (element->nextSibling);
NSLog(@"%@", [self getName:aPost]);
NSLog(@"name %@ content %@", aPost.name, aPost.content);
[self.postsArray insertObject:aPost atIndex:self.countingIndex];
self.countingIndex++;
element = nextElement;
}
} while ((element != nil));
return self.postsArray;
}
-(Post *)objectInListAtIndex:(NSUInteger)theIndex {
return [self.postsArray objectAtIndex:theIndex];
}
-(NSUInteger)countOfList {
return [self.postsArray count];
}
@end
邮政
#import <Foundation/Foundation.h>
@class Post;
@interface Post : NSObject
@property (nonatomic, weak) NSString *name;
@property (nonatomic, weak) NSString *author;
@property (nonatomic, weak) NSString *publicationDate;
@property (nonatomic, weak) NSString *content;
@property (nonatomic, weak) NSString *postURL;
@end
邮寄
#import "Post.h"
@implementation Post
- (id)init {
self = [super init];
if (self) {
self.name = @"";
self.author = @"";
self.content = @"";
self.publicationDate = @"";
self.postURL = @"";
}
return self;
}
@end
最佳答案
正如我在上面的评论中所述,问题是您在Post类中使用了弱引用。请尝试以下代码:
#import <Foundation/Foundation.h>
@class Post;
@interface Post : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *author;
@property (nonatomic, strong) NSString *publicationDate;
@property (nonatomic, strong) NSString *content;
@property (nonatomic, strong) NSString *postURL;
@end
如果要了解强引用和弱引用之间的区别,请看以下问题:
Differences between strong and weak in Objective-C
还要注意,objective-c属性的默认引用类型是
strong
,因此,如果需要,可以省略strong
关键字。关于ios - 调用某些函数时变量消失,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16050629/