Objective c 在调用任何类别方法之前,是否可以初始化类别中的属性?
是否可以初始化类别中的属性Objective c 在调用任何类别方法之前,是否可以初始化类别中的属性?,objective-c,objective-c-category,Objective C,Objective C Category,是否可以初始化类别中的属性 例如,如果我在一个类中有一个名为nameList的可变数组属性。在调用任何类别方法之前,是否可以为此类创建一个类别以将对象添加到数组属性中?否在目标c中不可能。类别是向现有类中仅添加方法的方法,而不能将属性添加到该类中。 读这个 不,这在目标c中是不可能的。Category是一种只向现有类添加方法的方法,您不能向其中添加属性。 读这个 当然,可以通过objc/runtime和objc\u getAssociatedObject/objc\u setAssociated
例如,如果我在一个类中有一个名为nameList的可变数组属性。在调用任何类别方法之前,是否可以为此类创建一个类别以将对象添加到数组属性中?否在目标c中不可能。类别是向现有类中仅添加方法的方法,而不能将属性添加到该类中。 读这个
不,这在目标c中是不可能的。Category是一种只向现有类添加方法的方法,您不能向其中添加属性。 读这个
当然,可以通过
objc/runtime
和objc\u getAssociatedObject
/objc\u setAssociatedObject
当然,可以通过
objc/runtime
和objc\u getAssociatedObject
/objc\u setAssociatedObject
如果我理解正确,而其他人对你的问题有不同的理解,那么你所拥有的是:
- 具有属性的类
- 那门课上的一个类别
init
方法,但使用类别
如果我的理解是正确的,那么答案是否定的,没有类别初始值设定项。因此,重新设计您的模型,不需要它,这可能只是使用一个子类,因为它提供了您所追求的行为
答案很长,您可以让所有的category方法执行检查,比如检查您想要更改的属性,看看是否有。如果检查属性无法确定对象是否已“类别初始化”,则可以使用关联对象(查看Apple的运行时文档)或其他方法来记录该事实
嗯
附录:更长/更复杂的解决方案…
GCC和Clang都支持一个函数(而不是方法)属性构造函数,该构造函数在加载时标记要调用的函数,该函数不接受任何参数,也不返回任何内容。例如,假设您有一个类Something
和一个类别More
,然后在类别实现文件中,通常称为Something+More.m
,您可以编写:
__attribute__((constructor)) static void initializeSomethingMore(void)
{
// do stuff
}
(静态停止符号初始化MethingMore全局可见,您既不想污染全局名称空间,也不想意外调用此函数-因此将其隐藏。)
此函数将被自动调用,非常类似于标准类+(void)initialize
方法。然后,您可以使用Objective-C运行时函数将类Something
的指定初始值设定项实例方法替换为您自己的实现。这些应该首先调用原始实现,然后在返回对象之前初始化类别。在大纲中,您定义了如下方法:
- (id) categoryVersionOfInit
{
self = [self categoryVersionOfInit]; // NOT a mistake, see text!
if (self)
{
// init category
}
return self;
}
然后在initializeMethingMore
中切换init
和categoryVersionFinit
的实现,因此对某物的实例调用init
实际上调用categoryVersionFinit
。现在您看到了在categoryVersionFinit
中进行明显的自递归调用的原因-在调用时,实现已经切换,因此调用调用了init
的原始实现。。。(如果你在这一点上斜视,就画一幅画!)
使用这种技术,您可以将类别初始化代码“注入”到类中。请注意,调用InitializeMethingMore
函数的确切点尚未定义,因此,例如,您不能假定它将在目标类用于初始化的任何方法之前或之后被调用(+initialize
,+load
或其自身的构造函数).如果我对你的理解正确,而其他人对你的问题有不同的理解,那么你所拥有的是:
- 具有属性的类
- 那门课上的一个类别
如果要在对给定实例调用任何类别方法之前自动调用特定方法,该方法将通过修改属性来“初始化”类别方法
换句话说,您需要一个子类的等价物及其init
方法,但使用类别
如果我的理解是正确的,那么答案是否定的,没有类别初始值设定项。因此,重新设计您的模型,不需要它,这可能只是使用一个子类,因为它提供了您所追求的行为
答案很长,您可以让所有的category方法执行检查,比如检查您想要更改的属性,看看是否有。如果检查属性无法确定对象是否已“类别初始化”,则可以使用关联对象(查看Apple的运行时文档)或其他方法来记录该事实
嗯
附录:更长/更复杂的解决方案…
GCC和Clang都支持一个函数(而不是方法)属性构造函数,该构造函数在加载时标记要调用的函数,该函数不接受任何参数,也不返回任何内容。例如,假设您有一个类Something
和一个类别More
,然后在类别实现文件中,通常称为Something+More.m
,您可以编写:
__attribute__((constructor)) static void initializeSomethingMore(void)
{
// do stuff
}
(静态
停止符号初始化MethingMore全局可见,您既不想污染全局名称空间,也不想意外调用此函数-因此隐藏