Posted By

iswear_wxp on 04/01/10


Tagged

coredata


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

adison


CoreData实例分析学习(2)


 / Published in: iPhone
 

URL: http://c.gzl.name/archives/412

  1. 在我们分析了程序主代理文件(AppDelegate)之后,我们先来看看一对自动生成的文件Event.h/.m
  2.  
  3. @interface Event : NSManagedObject {}
  4. @property (nonatomic, retain) NSDate *creationDate;
  5. @property (nonatomic, retain) NSNumber *latitude;
  6. @property (nonatomic, retain) NSNumber *longitude;
  7. @end
  8.  
  9. #import "Event.h"
  10. @implementation Event
  11. @dynamic creationDate;
  12. @dynamic latitude;
  13. @dynamic longitude;
  14. @end
  15.  
  16. 从上面我们能看出来,一个实体Event也就会被生成一个NSManagedObject(被管理对象),然后任何accessor和getter 都是被动态生成的,我们其实完全不用操任何的心,只需要在xcdatamodel文件里面配置后,点击添加文件,添加NSManagedObject文件,就会看到自动感知的类对象,然后生成就可以了。
  17.  
  18. 下面是根视图控制器,是一个列表视图(UITableViewController)
  19.  
  20. #import <CoreLocation/CoreLocation.h>
  21. @interface RootViewController : UITableViewController <CLLocationManagerDelegate> {
  22. //看到是UITableViewController的子类,由于需要使用Core Location,
  23. //所以在后面履行其protocal
  24. NSMutableArray *eventsArray;
  25. NSManagedObjectContext *managedObjectContext;
  26. //这个被管理对象内容器就是我们真正对Core Data数据的操作对象
  27. CLLocationManager *locationManager; //用来得到地理位置的Core Location对象
  28. UIBarButtonItem *addButton; //右上角的添加键
  29. }
  30. @property (nonatomic, retain) NSMutableArray *eventsArray;
  31. @property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
  32. @property (nonatomic, retain) CLLocationManager *locationManager;
  33. @property (nonatomic, retain) UIBarButtonItem *addButton;
  34. - (void)addEvent;
  35. @end
  36.  
  37. #import "RootViewController.h"
  38. #import "LocationsAppDelegate.h"
  39. #import "Event.h"
  40. @implementation RootViewController
  41. @synthesize eventsArray, managedObjectContext, addButton, locationManager;
  42.  
  43. - (void)viewDidLoad {
  44. [super viewDidLoad];
  45. self.title = @"Locations"; //设置列表视图的标题
  46. self.navigationItem.leftBarButtonItem = self.editButtonItem; //导航栏左边的编辑按钮
  47.  
  48. addButton = [[UIBarButtonItem alloc]
  49. initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
  50. target:self
  51. action:@selector(addEvent)]; //初始化添加按钮,
  52. addButton.enabled = NO; //在Core Location初始化之前将其关闭
  53. self.navigationItem.rightBarButtonItem = addButton;
  54. //把这个添加按钮添加到导航栏右侧
  55.  
  56. // 启动CLocation
  57. [[self locationManager] startUpdatingLocation];
  58.  
  59. //初始化一个“获取请求”到我们的实体“Event”
  60. NSFetchRequest *request = [[NSFetchRequest alloc] init];
  61. NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"
  62. inManagedObjectContext:managedObjectContext];
  63. [request setEntity:entity];
  64.  
  65. // 将时间以建立时间排序,最新的在最上
  66. NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
  67. NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
  68. [request setSortDescriptors:sortDescriptors];
  69. [sortDescriptor release];
  70. [sortDescriptors release];
  71.  
  72. // 执行“获取”操作,得到一个“可变数组”的拷贝
  73. NSError *error = nil;
  74. NSMutableArray *mutableFetchResults = [[managedObjectContext
  75. executeFetchRequest:request
  76. error:&error] mutableCopy];
  77. if (mutableFetchResults == nil) {
  78. //如果结果为空,在这作错误响应
  79. }
  80.  
  81. // 将得到的本地数组赋值到本类的全局数组,然后清理无用的对象
  82. [self setEventsArray:mutableFetchResults];
  83. [mutableFetchResults release];
  84. [request release];
  85. }
  86.  
  87. - (void)viewDidUnload {
  88. // 当视图被卸载后,将以下指针置空
  89. self.eventsArray = nil;
  90. self.locationManager = nil;
  91. self.addButton = nil;
  92. }
  93.  
  94. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  95. // 只有一个章节
  96. return 1;
  97. }
  98.  
  99. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  100. // 在数组里面有多少个对象,在列表视图就有多少行
  101. return [eventsArray count];
  102. }
  103.  
  104. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  105.  
  106. // 一个“日期格式化器”(凑合明白就好...)用来以特定的格式创建得到的日期
  107. static NSDateFormatter *dateFormatter = nil;
  108. if (dateFormatter == nil) {
  109. dateFormatter = [[NSDateFormatter alloc] init];
  110. [dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
  111. [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
  112. }
  113.  
  114. static NSNumberFormatter *numberFormatter = nil;
  115. if (numberFormatter == nil) {
  116. numberFormatter = [[NSNumberFormatter alloc] init];
  117. [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
  118. [numberFormatter setMaximumFractionDigits:3];
  119. }
  120.  
  121. static NSString *CellIdentifier = @"Cell";
  122.  
  123. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  124. if (cell == nil) {
  125. cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
  126. reuseIdentifier:CellIdentifier] autorelease];
  127. UITableViewCellStyleSubtitle;
  128. }
  129.  
  130. // 从数组中得到这个Event对象
  131. Event *event = (Event *)[eventsArray objectAtIndex:indexPath.row];
  132.  
  133. cell.textLabel.text = [dateFormatter stringFromDate:[event creationDate]];
  134.  
  135. NSString *string = [NSString stringWithFormat:@"%@, %@",
  136. [numberFormatter stringFromNumber:[event latitude]],
  137. [numberFormatter stringFromNumber:[event longitude]]];
  138. cell.detailTextLabel.text = string;
  139.  
  140. return cell;
  141. }
  142.  
  143. - (void)tableView:(UITableView *)tableView
  144. commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
  145. forRowAtIndexPath:(NSIndexPath *)indexPath
  146. {
  147.  
  148. if (editingStyle == UITableViewCellEditingStyleDelete) {
  149.  
  150. // 删除被惯例对象在索引路径(index path)
  151. NSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];
  152. [managedObjectContext deleteObject:eventToDelete];
  153.  
  154. // 更新数组和列表视图
  155. [eventsArray removeObjectAtIndex:indexPath.row];
  156. [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
  157.  
  158. // 提交更改到Core Data
  159. NSError *error;
  160. if (![managedObjectContext save:&error]) {
  161. // Handle the error.
  162. }
  163. }
  164. }
  165.  
  166. - (void)addEvent {
  167. //如果得不到位置,就返回.
  168. CLLocation *location = [locationManager location];
  169. if (!location) {
  170. return; }
  171.  
  172. //建立一个Event实体对象
  173. Event *event = (Event *)[NSEntityDescription
  174. insertNewObjectForEntityForName:@"Event"
  175. inManagedObjectContext:managedObjectContext];
  176.  
  177. //得到经纬度,然后赋值到event对象去
  178. CLLocationCoordinate2D coordinate = [location coordinate];
  179. [event setLatitude:[NSNumber numberWithDouble:coordinate.latitude]];
  180. [event setLongitude:[NSNumber numberWithDouble:coordinate.longitude]];
  181.  
  182. // 实例里面并没有使用CL的时间标签,因为在模拟器中会是一样的
  183. // [event setCreationDate:[location timestamp]];
  184. [event setCreationDate:[NSDate date]];
  185. //所以现在使用的是现在的时间,而不是得到位置的时候的时间
  186.  
  187. // 保存更改
  188. NSError *error;
  189. if (![managedObjectContext save:&error]) {
  190. // Handle the error.
  191. }
  192.  
  193. // 将新Event放到最上面,所以添加到0的位置
  194. // 然后滚动列表视图到最上面,如果没有那么多的数据是看不出来区别的
  195. [eventsArray insertObject:event atIndex:0];
  196. NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
  197. [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
  198. withRowAnimation:UITableViewRowAnimationFade];
  199. [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
  200. atScrollPosition:UITableViewScrollPositionTop animated:YES];
  201. }
  202.  
  203. - (CLLocationManager *)locationManager {
  204. //自定义的CLocation的getter,方便初始化
  205. if (locationManager != nil) {
  206. return locationManager;
  207. }
  208. //初始化CL对象,然后设置精准度,然后将代理对象设为本地
  209. locationManager = [[CLLocationManager alloc] init];
  210. [locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
  211. [locationManager setDelegate:self];
  212.  
  213. return locationManager;
  214. }
  215. //CLocation的一个代理方法,如果成功就开启右侧添加按钮
  216. - (void)locationManager:(CLLocationManager *)manager
  217. didUpdateToLocation:(CLLocation *)newLocation
  218. fromLocation:(CLLocation *)oldLocation {
  219. addButton.enabled = YES;
  220. }
  221. //CLocation的一个代理方法,如果失败了就关闭(disable)右侧添加按钮
  222. - (void)locationManager:(CLLocationManager *)manager
  223. didFailWithError:(NSError *)error {
  224. addButton.enabled = NO;
  225. }
  226.  
  227. - (void)dealloc {
  228. //释放对象
  229. [managedObjectContext release];
  230. [eventsArray release];
  231. [locationManager release];
  232. [addButton release];
  233. [super dealloc];
  234. }
  235. @end
  236.  
  237. 从上面的源代码,我们可以看出,
  238. 1,在这里数据并不是每次都由NSManagedContext对象得到,而是由一个数组得出。
  239. 2,数组是一个可变数组,由第一次载入的视图的时候从NSManagedContext中得到
  240. 3,从NSManagedContext对象中得到数据需要使用NSFetchRequest来初始化一个“获取”
  241. 4,每次获得新的数据的时候,同时保存到数组和NSManagedContext中,添加后需要对更改进行提交

Report this snippet  

You need to login to post a comment.