Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在调用任何类别方法之前,是否可以初始化类别中的属性?_Objective C_Objective C Category - Fatal编程技术网

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全局可见,您既不想污染全局名称空间,也不想意外调用此函数-因此隐藏