作者kevwalker (2A3C好声好好听)
看板MacDev
标题[问题] 用category加instance (Associated reference)
时间Fri Mar 25 12:17:20 2011
版上大大看到一定会说category不能加member
请用subclass...
不过小弟还是想说明一下状况,也许大家会有更好的方法。
过去我都在玩cocos2d,CCNode里本身就有一个userdata的变数可以供自由使用。
然而在UIKit里的UIView似乎没有留下这样一个空间,
最简单的方式就是去继承UIView,然後自己塞一个id userdata进去。
但是我希望的是,所有继承UIView的class都有userdata可以用。
也就是说,如果能让UIView可以set/get userdata,
那UIImageView, UIScrollView, UIxxxView都可以有userdata可以用。
小弟在网路上爬文後,发现可以用Associate reference + catgegory的方式实现
测试也成功了,但是网路上没看到实际范例,所以想请版上大大们帮忙check一下
首先先建一个class
//UserData.h
#import <Foundation/Foundation.h>
@interface UserData : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end
//UserData.m
#import "UserData.h"
@implementation UserData
@synthesize name;
@end
再来是myuserdata category
//myuserdata.h
@interface UIView (myuserdata)
- (void)setUserData:(NSString *)string;
- (NSString *)userData;
@end
//myuserdata.m
#import "myuserdata.h"
#import "UserData.h"
#import <objc/runtime.h>
static char key;
@implementation UIView (myuserdata)
- (void)setUserData:(NSString *)string {
if (!objc_getAssociatedObject(self, &key)) {
UserData *data = [[UserData alloc] init];
objc_setAssociatedObject(self, &key, data, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[data release];
}
UserData *userdata = objc_getAssociatedObject(self, &key);
userdata.name = string;
}
- (NSString *)userData {
UserData *userdata = objc_getAssociatedObject(self, &key);
return userdata.name;
}
@end
我是在iOS下UIViewController里测
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *myclass = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[myclass setBackgroundColor:[UIColor redColor]];
[myclass setUserData:@"this is myclass userdata"];
[self.view addSubview:myclass];
[myclass release];
NSLog([myclass userData]);
UIImageView *imag = [[UIImageView alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
[imag setImage:[UIImage imageNamed:@"AudioImage.png"]];
[imag setBackgroundColor:[UIColor blueColor]];
[imag setUserInteractionEnabled:YES];
[imag setUserData:@"this is imag userdata"];
[self.view addSubview:imag];
[imag release];
NSLog([imag userData]);
}
可以work,这麽做是ok的吗?
还是有其它更好的方法?
(不好意思,code直接放bbs,伤大家眼睛了)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.115.120.152
※ 编辑: kevwalker 来自: 140.115.120.152 (03/25 12:18)
1F:推 popcorny:感谢分享..又学到一招!! 03/25 13:30
2F:→ ttflee:UIView的layer是Key-value compliant的。 03/25 20:04
4F:推 aecho:咦?Key-value compliant好棒,感谢分享。 03/26 02:49