使用KVO观察多个对象的同时变化

时间:2014-08-06 03:23:06

标签: ios objective-c cocoa-touch key-value-observing

我有一个LineView类,显示两点之间的一条线。 LineView基本上只是一个矩形视图,thickness代表高度,其startPointendPoint的位置决定了矩形的宽度以及我的旋转将(使用CGAffineTransform)应用于矩形。

@interface LineView : UIView
@property (nonatomic) float thickness;
@property (nonatomic, strong) (PointView *)startPoint;
@property (nonatomic, strong) (PointView *)endPoint;

PointView类定义屏幕上的移动点。由于我希望始终在其起点和终点之间显示该行,因此我LineView会观察centerstartPoint的{​​{1}}属性},像这样:

endPoint

- (void)setStartPoint:(PointView *)startPoint { // Un-observe previous startPoint [_startPoint removeObserver:self forKeyPath:@"center"]; _startPoint = startPoint; // Observe new startPoint [_startPoint addObserver:self forKeyPath:@"center" options:0 context:nil]; [self updateLine]; } 的定义相似。因此,每当(void)setEndPoint:(PointView *)endPoint属性发生更改时,我都要更新该行:

center

这里- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (![keyPath isEqualToString:@"center"]) { return; } if (object == self.startPoint || object == self.endPoint) { [self updateLine]; } }

(void)updateLine:

- (void)updateLine { CGPoint startPoint = self.startPoint.center; CGPoint endPoint = self.endPoint.center; // tangent vector CGPoint tangent = cgpSubtract(endPoint, startPoint); // determine the angle of the tangent vector float angle = cgpAngle(tangent); // determine the length of the tangent vector float length = cgpLength(tangent); // frame is undefined when transform is not identity self.transform = CGAffineTransformIdentity; // set frame.origin to startPoint, and frame.size to length and thickness self.frame = CGRectMake(startPoint.x, startPoint.y, length, self.thickness); // rotate the view so that the line properly connects startPoint and endPoint self.transform = CGAffineTransformMakeRotation(angle); [self setNeedsDisplay]; } 函数只是我定义为执行简单cgp数学运算的静态方法。

因此,只要CGPointstartPoint在屏幕上移动,endPoint属性会更改移动点,center会观察到此更改并调用{ {1}}更新自己。

现在让我们说随着时间的推移我们会在屏幕上移动LineViewupdateLine。实际上,我们有一个startPoint类,其中包含endPoint属性:

Timeline

并且currentTime类设置为观察此@interface Timeline : NSObject @property (nonatomic) float currentTime; ... 属性,并在PointView更改时更改其currentTime位置。

通过这种方式,center取决于currentTime,而PointView取决于两个Timeline,但LineView不依赖于PointView 1}}。它不需要知道LineView是什么,它需要知道的是它的起点和终点Timeline的位置。这是好设计,对吗?

那么,当currentTime发生变化时,centercurrentTime都会发生变化,然后startPoint.center对象的endPoint.center被调用两次。理想情况下,我只想要updateLine一次被调用,因为我真的只需要更新一次线来反映所做的更改"同时"两点。有没有办法做到这一点?

在这个示例中,两次调用LineView似乎并不是什么大不了的事。但是如果我定义某种由{100}定义的updateLine怎么办?然后,当我更新updateLine时,所有100个PolygonView中的所有100个PointView都会更新,而这会依次调用currentTime 100次,设置center }和PointView属性100次,这似乎效率很低。

所以这里的主要问题是,对于一个观察多个其他对象的对象,当updatePolygon观察到的对象被更改时,我怎样才能让这个对象更新一次"同时"而不是{ {1}}次?

我意识到"同时"因为这些变化不是同时处理的,所以在这里并不完全合适;每个frame在运行时按顺序更新。但是,我找不到更好的词来描述这种情况。

0 个答案:

没有答案