CoreData实例分析学习(2)

来源:互联网 发布:centos ftp服务开启 编辑:程序博客网 时间:2024/05/16 05:52

在我们分析了程序主代理文件(AppDelegate)之后,我们先来看看一对自动生成的文件Event.h/.m

@interface Event : NSManagedObject  {}@property (nonatomic, retain) NSDate *creationDate;@property (nonatomic, retain) NSNumber *latitude;@property (nonatomic, retain) NSNumber *longitude;@end
#import "Event.h"@implementation Event@dynamic creationDate;@dynamic latitude;@dynamic longitude;@end

从上面我们能看出来,一个实体Event也就会被生成一个NSManagedObject(被管理对象),然后任何accessor和getter都是被动态生成的,我们其实完全不用操任何的心,只需要在xcdatamodel文件里面配置后,点击添加文件,添加NSManagedObject文件,就会看到自动感知的类对象,然后生成就可以了。

下面是根视图控制器,是一个列表视图(UITableViewController)

#import <CoreLocation/CoreLocation.h>@interface RootViewController : UITableViewController <CLLocationManagerDelegate> {//看到是UITableViewController的子类,由于需要使用Core Location,//所以在后面履行其protocal    NSMutableArray *eventsArray;NSManagedObjectContext *managedObjectContext;//这个被管理对象内容器就是我们真正对Core Data数据的操作对象    CLLocationManager *locationManager; //用来得到地理位置的Core Location对象    UIBarButtonItem *addButton;//右上角的添加键}@property (nonatomic, retain) NSMutableArray *eventsArray;@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;@property (nonatomic, retain) CLLocationManager *locationManager;@property (nonatomic, retain) UIBarButtonItem *addButton;- (void)addEvent;@end
#import "RootViewController.h"#import "LocationsAppDelegate.h"#import "Event.h"@implementation RootViewController@synthesize eventsArray, managedObjectContext, addButton, locationManager; - (void)viewDidLoad {    [super viewDidLoad];    self.title = @"Locations"; //设置列表视图的标题    self.navigationItem.leftBarButtonItem = self.editButtonItem; //导航栏左边的编辑按钮     addButton = [[UIBarButtonItem alloc]                initWithBarButtonSystemItem:UIBarButtonSystemItemAdd                target:self                action:@selector(addEvent)]; //初始化添加按钮,addButton.enabled = NO; //在Core Location初始化之前将其关闭    self.navigationItem.rightBarButtonItem = addButton;    //把这个添加按钮添加到导航栏右侧 // 启动CLocation[[self locationManager] startUpdatingLocation]//初始化一个“获取请求”到我们的实体“Event”NSFetchRequest *request = [[NSFetchRequest alloc] init];NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];[request setEntity:entity]// 将时间以建立时间排序,最新的在最上NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];[request setSortDescriptors:sortDescriptors];[sortDescriptor release];[sortDescriptors release]// 执行“获取”操作,得到一个“可变数组”的拷贝NSError *error = nil;NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];if (mutableFetchResults == nil) {//如果结果为空,在这作错误响应} // 将得到的本地数组赋值到本类的全局数组,然后清理无用的对象[self setEventsArray:mutableFetchResults];[mutableFetchResults release];[request release];} - (void)viewDidUnload {// 当视图被卸载后,将以下指针置空self.eventsArray = nil;self.locationManager = nil;self.addButton = nil;} - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {// 只有一个章节    return 1;} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {// 在数组里面有多少个对象,在列表视图就有多少行    return [eventsArray count];} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 一个“日期格式化器”(凑合明白就好...)用来以特定的格式创建得到的日期    static NSDateFormatter *dateFormatter = nil;if (dateFormatter == nil) {dateFormatter = [[NSDateFormatter alloc] init];[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];[dateFormatter setDateStyle:NSDateFormatterMediumStyle];} static NSNumberFormatter *numberFormatter = nil;if (numberFormatter == nil) {numberFormatter = [[NSNumberFormatter alloc] init];[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];[numberFormatter setMaximumFractionDigits:3];}     static NSString *CellIdentifier = @"Cell";     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];    if (cell == nil) {        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];UITableViewCellStyleSubtitle;    } // 从数组中得到这个Event对象Event *event = (Event *)[eventsArray objectAtIndex:indexPath.row]; cell.textLabel.text = [dateFormatter stringFromDate:[event creationDate]]NSString *string = [NSString stringWithFormat:@"%@, %@",[numberFormatter stringFromNumber:[event latitude]],[numberFormatter stringFromNumber:[event longitude]]];    cell.detailTextLabel.text = stringreturn cell;} - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {     if (editingStyle == UITableViewCellEditingStyleDelete) {         // 删除被惯例对象在索引路径(index path)NSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];[managedObjectContext deleteObject:eventToDelete]// 更新数组和列表视图        [eventsArray removeObjectAtIndex:indexPath.row];        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]// 提交更改到Core DataNSError *error;if (![managedObjectContext save:&error]) {// Handle the error.}    }} - (void)addEvent {//如果得不到位置,就返回.CLLocation *location = [locationManager location];if (!location) {return; }  //建立一个Event实体对象Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext]//得到经纬度,然后赋值到event对象去CLLocationCoordinate2D coordinate = [location coordinate];[event setLatitude:[NSNumber numberWithDouble:coordinate.latitude]];[event setLongitude:[NSNumber numberWithDouble:coordinate.longitude]]// 实例里面并没有使用CL的时间标签,因为在模拟器中会是一样的// [event setCreationDate:[location timestamp]];[event setCreationDate:[NSDate date]]; //所以现在使用的是现在的时间,而不是得到位置的时候的时间 // 保存更改NSError *error;if (![managedObjectContext save:&error]) {// Handle the error.} // 将新Event放到最上面,所以添加到0的位置// 然后滚动列表视图到最上面,如果没有那么多的数据是看不出来区别的[eventsArray insertObject:event atIndex:0];NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];} - (CLLocationManager *)locationManager {//自定义的CLocation的getter,方便初始化    if (locationManager != nil) {return locationManager;}//初始化CL对象,然后设置精准度,然后将代理对象设为本地locationManager = [[CLLocationManager alloc] init];[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];[locationManager setDelegate:self]return locationManager;}//CLocation的一个代理方法,如果成功就开启右侧添加按钮- (void)locationManager:(CLLocationManager *)manager    didUpdateToLocation:(CLLocation *)newLocation           fromLocation:(CLLocation *)oldLocation {    addButton.enabled = YES;}//CLocation的一个代理方法,如果失败了就关闭(disable)右侧添加按钮- (void)locationManager:(CLLocationManager *)manager       didFailWithError:(NSError *)error {    addButton.enabled = NO;} - (void)dealloc {//释放对象[managedObjectContext release];[eventsArray release];    [locationManager release];    [addButton release];    [super dealloc];}@end

从上面的源代码,我们可以看出,
1,在这里数据并不是每次都由NSManagedContext对象得到,而是由一个数组得出。
2,数组是一个可变数组,由第一次载入的视图的时候从NSManagedContext中得到
3,从NSManagedContext对象中得到数据需要使用NSFetchRequest来初始化一个“获取”
4,每次获得新的数据的时候,同时保存到数组和NSManagedContext中,添加后需要对更改进行提交

原创粉丝点击