形状应用的数据对象操作与优化
立即解锁
发布时间: 2025-08-26 00:37:09 阅读量: 7 订阅数: 10 


iOS核心数据高级编程指南
### 形状应用的数据对象操作与优化
#### 1. 启用形状应用的用户交互
在完成应用的 Core Data 部分后,虽然可以构建并运行应用,但界面上并没有明显变化。此时需要添加用户界面元素来实现形状的创建、更新和删除操作。
##### 1.1 创建形状
创建形状的用户界面操作是点击屏幕。因此,需要在 `ShapesViewController.m` 中添加方法来捕获屏幕点击事件,确定点击位置,根据画布进行位置缩放,并调用 `createShapeAt:` 方法传入点击点。具体代码如下:
```objc
#pragma mark - Touch events handling
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
// Where did the view get touched?
CGPoint location = [touch locationInView: touch.view];
// Scale according to the canvas’ transform
float scale = [(BasicCanvasUIView *)touch.view scale];
location = CGPointMake(location.x / scale, location.y / scale);
// Create the shape
[self createShapeAt:location];
}
```
完成上述代码添加后,就可以构建并运行应用,点击屏幕几次,会发现无论点击屏幕的上半部分还是下半部分,形状都会显示,且上半部分的形状大小是下半部分的两倍。旋转屏幕,形状依然会正常显示。
##### 1.2 更新形状
更新形状的用户界面操作是旋转设备。因此,需要添加方法来检测设备旋转,并在其中调用 `updateAllShapes` 方法。代码如下:
```objc
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
[self updateAllShapes];
}
```
##### 1.3 删除形状
检测设备摇晃以删除所有形状的操作相对复杂一些。`ShapeViewController` 在其视图显示时必须成为第一响应者,因此需要添加使它有资格成为第一响应者的方法,并在 `viewDidAppear` 方法中使其成为第一响应者。具体代码如下:
```objc
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
```
然后添加检测摇晃事件的方法,并在其中调用 `deleteAllShapes` 方法:
```objc
#pragma mark - Shake events handling
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.subtype == UIEventSubtypeMotionShake) {
[self deleteAllShapes];
}
}
```
至此,形状应用的基本功能就完成了。可以构建、运行应用,进行点击、旋转和摇晃操作,应该能看到形状的出现、颜色变化和消失。
#### 2. 生成自定义类
为了让应用代码更加清晰和易于维护,可以使用自定义数据对象来替代 `NSManagedObject` 实例。以下是生成自定义类的步骤:
1. **选择生成方式**:可以手动创建类,也可以让 Xcode 自动生成。使用 Xcode 生成类的步骤如下:
- 选择 `File ➤ New ➤ New File`。
- 在左侧选择 `iOS` 下的 `Core Data`,右侧选择 `NSManagedObject subclass`。
- 点击 `Next`,在随后的对话框中选择 `Shapes` 数据模型。
- 点击 `Next`,在下一个对话框中选择要生成类的实体,全部选择后点击 `Next`。
- 最后在对话框中点击 `Create` 保存生成的类。
2. **组织代码**:为了保持代码的组织性,建议创建一个类组来存储数据对象。在 Xcode 中,选择所有生成的类,右键点击并选择 `New Group from Selection`,将新组重命名为 `Managed Objects`。
3. **验证类的使用**:Xcode 会更新模型以使用生成的类。可以在 `Data Model` 检查器中显示任何实体的属性,`Class` 字段应该显示生成的类名,而不是 `NSManagedObject`。
以下是部分生成类的代码示例:
- **Vertex.h**
```objc
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Polygon;
@interface Vertex : NSManagedObject
@property (nonatomic, retain) NSNumber * y;
@property (nonatomic, retain) NSNumber * x;
@property (nonatomic, retain) NSNumber * index;
@property (nonatomic, retain) Polygon * polygon;
@end
```
- **Transform.h(原始)**
```objc
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Transform : NSManagedObject
@property (nonatomic, retain) NSNumber * scale;
@property (nonatomic, retain) NSManagedObject * canvas;
@end
```
- **Transform.h(更新后)**
```objc
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Canvas;
@interface Transform : NSManagedObject
@property (nonatomic, retain) NSNumber * scale;
@property (nonatomic, retain) Canvas * canvas;
@end
```
同时,对于更新的头文件,需要在相应的实现文件中添加适当的头文件。例如,在 `Transform.m` 中添加 `#import "Canvas.h"`。
生成类的实现通常使用 `@dynamic` 指令,以 `Vertex.m` 为例:
```objc
#import "Vertex.h"
#import "Polygon.h"
@implementation Vertex
@dynamic y;
@dynamic x;
@dynamic index;
@dynamic polygon;
@end
```
#### 3. 使用自定义类更新应用代码
在创建自定义对象后,可以直接使用它们的属性,而不是通过 `valueForKey:` 方法。首先在 `ShapesViewController.m` 中添加所有新创建对象的导入语句:
```objc
#import "Polygon.h"
#import "Circle.h"
#import "Shape.h"
#import "Canvas.h"
#import "Vertex.h"
#import "Transform.h"
```
然后更新 `createShapeAt:` 方法,使用新类来创建形状。以下是更新后的代码:
```objc
- (void)createShapeAt:(CGPoint)point {
// Create a managed object to store the shape
Shape *shape = nil;
// Randomly choose a Circle or a Polygon
int type = arc4random() % 2;
if (type == 0) { // Circle
// Create the Circle managed object
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Circle"
inManagedObjectContext:self.managedObjectContext];
Circle *circle = [NSEntityDescription insertNewObjectForEntityForName:[entity name]
inManagedObjectContext:self.managedObjectContext];
shape = circle;
// Randomly create a radius and set the attributes of the circle
float radius = 10 + (arc4random() % 90);
circle.x = [NSNumber numberWithFloat:point.x];
circle.y = [NSNumber numberWithFloat:point.y];
circle.radius = [NSNumber numberWithFloat:radius];
NSLog(@"Made a new circle at (%f,%f) with radius %f", point.x, poin
```
0
0
复制全文
相关推荐










