何时在Objective-C中使用关联对象 [英] When to use associated objects in objective-c

查看:60
本文介绍了何时在Objective-C中使用关联对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近了解了Objective-C中的关联对象以及如何实现它们.根据我的理解,如果您拥有一个只希望对象的单个实例具有的属性,它们将非常有用.

I have recently learned about associated objects in objective-c and how to implement them. From my understanding, they are helpful if you have a property that you want only a single instance of an object to have.

我无法在Objective-C中想到关联对象的任何特定用例(这意味着我无法使用其他某种方式来使用这些用例).

I can't think of any specific use cases for associated objects in objective-c (meaning use cases that I can't do using some other means).

有人有何时使用关联对象的具体示例吗?

Does anyone have specific examples of when to use associated objects?

推荐答案

关联对象的常见用例是,当您需要将自己的数据附加到某个对象但不能修改类或创建子类时,要么是因为它不是为子类设计的,要么是因为您无法控制对象的创建方式.这也是创建类别的常见原因,因此在类别中使用关联的对象很常见.

The common use case for an associated object is when you need to attach your own data to some object but you can't modify the class or create a subclass, either because it's not designed for subclassing or because you have no control over how the object is created. This is also a common reason to create a category, so it's common to use associated objects in a category.

例如,假设您要创建一个绘图应用程序,以支持同时进行多点触摸的绘图.您希望每次触摸在屏幕上创建一条独立的曲线.最好为每个触摸添加两个属性:path属性(用于在触摸移动时构造曲线)和shapeLayer属性(用于在屏幕上显示曲线).

For example, suppose you want to create a drawing app that supports drawing with multiple touches simultaneously. You want each touch to create an independent curve on the screen. It would be nice if you could add two properties to each touch: a path property (for constructing the curve as the touch moves) and a shapeLayer property (for displaying the curve on the screen).

但是您无法控制UITouch对象的创建. UIKit会创建每个UITouch对象而没有任何钩子,供您使用添加属性的子类.

But you have no control over the creation of UITouch objects. UIKit creates each UITouch object without any hook for you to use a subclass that adds your properties.

相反,您可以在UITouch上创建一个类别以添加您的属性:

Instead, you can create a category on UITouch that adds your properties:

#import <UIKit/UIKit.h>

@interface UITouch (Rob_Sketch)

@property (nonatomic, readwrite, setter=Rob_setPath:) UIBezierPath *Rob_path;
@property (nonatomic, readwrite, setter=Rob_setShapeLayer:) CAShapeLayer *Rob_shapeLayer;

@end

UITouch+Rob_Sketch.m

#import "UITouch+Rob_Sketch.h"
#import <objc/runtime.h>

static const char *const UITouch_Rob_Sketch_PathKey = "UITouch_Rob_Sketch_PathKey";
static const char *const UITouch_Rob_Sketch_ShapeLayerKey = "UITouch_Rob_Sketch_ShapeLayerKey";

@implementation UITouch (Rob_Sketch)

- (UIBezierPath *)Rob_path {
    return objc_getAssociatedObject(self, UITouch_Rob_Sketch_PathKey);
}

- (void)Rob_setPath:(UIBezierPath *)path {
    objc_setAssociatedObject(self, UITouch_Rob_Sketch_PathKey, path,
        OBJC_ASSOCIATION_RETAIN);
}

- (CAShapeLayer *)Rob_shapeLayer {
    return objc_getAssociatedObject(self, UITouch_Rob_Sketch_ShapeLayerKey);
}

- (void)Rob_setShapeLayer:(CAShapeLayer *)layer {
    objc_setAssociatedObject(self, UITouch_Rob_Sketch_ShapeLayerKey, layer,
        OBJC_ASSOCIATION_RETAIN);
}

@end

然后,在控制器中,您可以使用类别访问每次触摸的路径和形状层:

Then, in your controller, you can use the category to access the path and shape layer of each touch:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        touch.Rob_path = [UIBezierPath bezierPath];
        [touch.Rob_path moveToPoint:[touch locationInView:touch.view]];
        touch.Rob_shapeLayer = [self newShapeLayer];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        [touch.Rob_path addLineToPoint:[touch locationInView:touch.view]];
        touch.Rob_shapeLayer.path = touch.Rob_path.CGPath;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        [touch.Rob_shapeLayer removeFromSuperlayer];
        [self addPathToDrawing:touch.Rob_path];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        [touch.Rob_shapeLayer removeFromSuperlayer];
    }
}

这篇关于何时在Objective-C中使用关联对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆