所有 SKNode 类都提供了一个 userData 属性,可用于此目的。
您可以编写一个 Objective-C 类别,通过它您可以添加其他属性而无需子类化。下面是一个经过验证的模式。
界面:
#import "YourCustomObject.h"
@interface SKNode (customObject)
@property (nonatomic) YourCustomObject* yourCustomObject;
@end
实施:
static NSString* YourCustomObjectUserDataKey = @"YourCustomObjectUserDataKey";
@implementation SKNode (customObject)
-(NSMutableDictionary*) internal_getOrCreateUserData
{
NSMutableDictionary* userData = self.userData;
if (userData == nil)
{
userData = [NSMutableDictionary dictionary];
self.userData = userData;
}
return userData;
}
-(void) setYourCustomObject:(YourCustomObject*)customObject
{
NSMutableDictionary* userData = [self internal_getOrCreateUserData];
[userData setObject: customObject forKey:YourCustomObjectUserDataKey];
}
-(YourCustomObject*) yourCustomObject
{
NSMutableDictionary* userData = [self internal_getOrCreateUserData];
return (YourCustomObject*)[userData objectForKey:YourCustomObjectUserDataKey];
}
@end
将YourCustomObject 替换为您的实际班级名称。
类别当然可以扩展为托管多个属性,您不必为每个属性编写单独的类别。该类别也不必在 SKNode 上,如果您需要其他属性但只在 SKSpriteNode 上,您可以将此作为 SKSpriteNode 上的类别。
您经常需要访问YourCustomObject 中的拥有节点。
因此,最好提供一个将拥有节点作为输入的初始化程序和/或属性。我更喜欢只读属性和自定义初始化程序,因为通常您不希望所有者在对象的整个生命周期内更改。非常重要:此属性必须为 weak 才能不创建保留循环。
@interface YourCustomObject
@property (weak, readonly) SKNode* owningNode;
+(instancetype) customObjectWithOwningNode:(SKNode*)owningNode;
@end
@implementation YourCustomObject
+(instancetype) customObjectWithOwningNode:(SKNode*)owningNode
{
return [[self alloc] initWithOwningNode:owningNode];
}
-(id) initWithOwningNode:(SKNode*)owningNode
{
self = [super init];
if (self)
{
_owningNode = owningNode;
}
return self;
}
@end
然后您可以在节点类中创建和分配您的自定义对象:
YourCustomObject* customObject = [YourCustomObject customObjectWithOwningNode:self];
self.yourCustomObject = customObject;