使用基于变量的属性扩展 Objective-c 中的类 [英] extend class in objective-c with variable based property

查看:45
本文介绍了使用基于变量的属性扩展 Objective-c 中的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Objective-c 中有一个表单实现,我想扩展我的小部件(NSButton、NSTextField 等)以包含额外的字符串,表示在提交事件发生后要使用的唯一标识符字符串,其中json 的触发器生成包含所有小部件 id/value 对.

I've got a form implementation in objective-c and I'd like to extend my widgets (NSButton, NSTextField, etc..) to contain additional string representing their unique identifier string to be used after submit event occur, which trigger generation of json contain all widget id/value pairs.

我已经尝试使用类别来扩展 NSControl,它是所有这些小部件的共同父级.

I've tried using categories to extend NSControl which is the common parent of all those widgets in the following way.

NSControl+formItemSupport.h
-------------------------------

@interface NSControl (formItemSupport)

@property NSString * formItemId;

@end

NSControl+formItemSupport.m
-------------------------------
@implementation NSControl (formItemSupport)

-(NSString *)formItemId {
    return self.formItemId;
}

-(void)setFormItemId:(NSString *)formItemId {
    self.formItemId = formItemId;
}


在我从 NSControl+formItemSupport.m 导入的 form.m 文件中,但是当我尝试在 NSButton : NSControl 对象中设置此字段时.但是,当我尝试设置属性 formItemId 时,我进入了无限循环.也许还有另一种方法可以在不使用继承的情况下使用基于变量的属性扩展 objc 类?

in the form.m file I import from NSControl+formItemSupport.m but when I try to set this field in NSButton : NSControl object. However, when I try to set the property formItemId, I get into infinite loop. Perhaps there's another way for extending objc class with variable based property without using inheritance ?

推荐答案

你可以

@synthesize formItemId = _formItemId;

//synthesize needs local declaration of _formItemId;
@implementation ExtraWurst {
    NSString *_formItemId;
}

但是这是在没有@synthesize 的情况下从 Xcode 为您在幕后完成的.
有时,以这种方式为属性定义内部变量的使用会更容易.

but this is done behind the scene for you from Xcode without @synthesize.
Sometime it is still easier to define the use of an internal variable for a property in this way.

除此之外,您可以并且必须通过以下方式更改 setter 和 getter 方法.

apart from that you can and have to change your setter and getter methods in the following way.

-(NSString *)formItemId {
    return _formItemId;
}

-(void)setFormItemId:(NSString *)formItemId {
    _formItemId = formItemId;
}

这将防止您陷入循环.

为什么?
因为 self.formItemId = 指的是 -(void)setFormItemId:
因此,您可以在 setter 中调用 setter,该 setter 将一次又一次地设置相同的值,也就是无限循环.你可以像上面一样处理 getter.

Why?
Because self.formItemId = refers to -(void)setFormItemId:
So you would call the setter inside the setter that will set with the same again and again aka an endless loop. You can take care of the getter the same way as shown above.

那么在哪里使用 self.yourProperty?
您可以在类中的任何位置使用 self.formItemId,但不能在 formItemId 的 getter 和 setter 内使用.

Where to use self.yourProperty then?
You can use self.formItemId anywhere in the class but not inside getter and setter of formItemId.

说得对,实例变量不能放在类别中.这意味着如果你需要这样你必须继承 UIControl 但这破坏了你使用的 UIControls 的继承.您必须对以后使用的所有 SpecialUIControl 进行子类化.

Correctly mentioned, Instance variables may not be placed in categories. Meaning if you need such you have to subclass UIControl but that breaks the inheritance of your used UIControls. You would have to subclass all your SpecialUIControls you are using later.

另一种解决方案,您可以在您的实现中定义一个常量,并使用 Objective-C 运行时函数并自己关联这个常量.请注意,因为您会为所有 UIControl 类转换 ObjectModel,然后..

Another solution, you could define a constant in your implementation and go with objective-C runtime functions and associate this constant yourself. Beware because you transform the ObjectModel for all UIControl classes then..

#import "NSControl+formItemSupport.h"
#import <objc/runtime.h>

@implementation UIControl (formItemSupport)
NSString const *key = @"formItemSupport.forItemKey";
-(void)setFormItemId:(NSString *)formItemId {
    objc_setAssociatedObject(self, &key, formItemId, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)formItemId {
    return objc_getAssociatedObject(self, &key);
}
@end

仍然,将您自己的 UIControl 子类化而不是扩展从 UIControl 继承的所有子类更容易、更安全和灵活.
为什么在这里子类化更容易?
正如您提到的,您想稍后使用每个控件的给定 formItemId 进行 json,您可以使用您的子类的归档程序/解归档程序设计模式,这些模式稍后可以进行 jsonify.

still, its much easier and safer and flexible to subclass your own UIControl instead to extent all subclasses inherited from UIControl.
Why is subclassing easier here?
As you mentioned you want to json later on with the given formItemId per Control you can make use of an archiver / unarchiver design pattern of your subclasses which are nice to jsonify later.

这篇关于使用基于变量的属性扩展 Objective-c 中的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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