Objective-C 子类基础,如何添加自定义属性;
Posted
技术标签:
【中文标题】Objective-C 子类基础,如何添加自定义属性;【英文标题】:Objective-C sub-classing basics, how to add custom property; 【发布时间】:2011-03-13 02:13:00 【问题描述】:我在子类化 MKPolygon
时遇到问题。
我想添加一个简单的 int tag
属性,但我不断获取 MKPolygon 的实例而不是我的自定义类,因此调用 setTag:
会导致异常。
问题是 MKPolygons 是使用类方法创建的:polygonWithCoordinates: count:
我不知道如何将其转换为我的类的实例(包括 tag 属性)。
您将如何向 MKPolygon 添加标签属性?
谢谢!
【问题讨论】:
【参考方案1】:您应该同时使用类别(如 @Seva 建议的那样)和 objc_setAssociatedObject(如 @hoha 建议的那样)。
@interface MKPolygon (TagExtensions)
@property (nonatomic) int tag;
@end
@implementation MKPolygon (TagExtensions)
static char tagKey;
- (void) setTag:(int)tag
objc_setAssociatedObject( self, &tagKey, [NSNumber numberWithInt:tag], OBJC_ASSOCIATION_RETAIN );
- (int) tag
return [objc_getAssociatedObject( self, &tagKey ) intValue];
@end
您可能还想查看Associative References section of the ObjC Guide,除了@hoha 链接到的API。
【讨论】:
别忘了#import <objc/runtime.h>
【参考方案2】:
看起来MKPolygon
的开发人员并没有使其继承友好。如果你只想给这个实例添加一些标签,你可以
1) 保留从MKPolygon
实例地址到标签的映射(NSDictionary 或 CFDictionary)。如果所有标签都需要在它们设置的同一类中,则此解决方案效果很好。
2) 使用运行时将标签直接附加到多边形 - objc_setAssociatedObject
(Objective-C Runtime Reference)
【讨论】:
【参考方案3】:我也面临同样的问题。一个简单的解决方案是仅使用 MKPolygon 的 Title 属性来保存您将保存在 Tag 中的内容。至少在我不需要对象引用而是一个简单数字的情况下,它可以工作
【讨论】:
title 在 MKPolygon 上可用,因为 MKPolygon 符合 MKAnnotation 协议。但 title 和 subtitle 是只读属性。因此,我想知道您是如何设法在 title 属性上设置值的?【参考方案4】:SpecialPolygon *polygon = [SpecialPolygon polygonWithCoordinates:count:];
[polygon setInt: 3];
关键是通过使用SpecialPolygon
工厂方法而不是MKPolygon
工厂方法,您将获得所需的SpecialPolygon
子类。
【讨论】:
也许,也许不是。不能保证所有便利构造函数的假设。便利构造函数可以调用[[[self class] alloc] init...]
,或者它可以在便利ctor中指定类:[[MKPolygon alloc] init...]
。如果是前者,那么你没问题,但后者不会返回SpecialPolygon
。问题是它有点骇人听闻/不受支持,并且不能保证在多个版本中都能正常工作。所以你必须制作自己的便利构造函数,它也初始化标签,并检查返回类型。但是,在某些情况下,这是一个不错的解决方案,所以 +1
如果是后者,你改成前者。但它应该只是self
而不是[self class]
,因为self
是一个类。
在 MKPolygon 子类的情况下不起作用。 [SpecialPolygon polygonWithCoordinates:count:] 会给你一个 MKPolygon。【参考方案5】:
您是在谈论由您的代码或其他地方创建的 MKPolygons 吗?如果是前者,只需覆盖 polygonWithStuff 方法。如果是后者,请考虑 MKPolygon 上的类别。然后你项目中的所有 MKPolygons 都会有一个标签。
【讨论】:
恐怕重写polygonWithCoordinates:count:
没有多大用处,因为在新实现中没有对应的init<...>
方法可以调用。
分类方法听起来很有趣,我从未使用过分类,但我现在会尝试并告诉你它是怎么回事。【参考方案6】:
由于作者似乎竭尽全力阻止您进行子类化(至少,这是公共接口的一个可能动机),请考虑使用一种组合形式:
http://en.wikipedia.org/wiki/Object_composition
【讨论】:
通常是一个不错的选择...但如果他必须将他的新对象传递给期望 MKPolygon 对象的 API 方法,这不一定适用。以上是关于Objective-C 子类基础,如何添加自定义属性;的主要内容,如果未能解决你的问题,请参考以下文章
iOS 11 中的 SafeArea:如何在没有安全区域的情况下使用自定义导航栏在主屏幕上添加来自 Objective-c 代码的视图
使用来自 XIB 的自定义 NSView/UIView 子类?
IOS/Objective-C:UIActivityViewController:针对不同的Activity类型进行自定义
IOS / Objective-C / Storyboard:从左到右的自定义Segue在视图控制器之间创建黑条