IOS/Objective-C:从类内方法调用常规self方法

IOS/Objective-C:从类内方法调用常规self方法,ios,objective-c,class,Ios,Objective C,Class,我有一个类方法,我通过以下方式调用它: #import myClass.h; [MYClass classMethod]; In myClass, I have a method as follows: +(void)classMethod { NSLog(@"classMethod called"); [self otherMethod]; } -(void) otherMethod { NSLog(@"other method called"); } 但是,这会引发未知的选择器错误

我有一个类方法,我通过以下方式调用它:

#import myClass.h;

[MYClass classMethod];

In myClass, I have a method as follows:

+(void)classMethod {
NSLog(@"classMethod called");
[self otherMethod];
}

-(void) otherMethod {
NSLog(@"other method called");
}
但是,这会引发未知的选择器错误

我的理解是self是指类方法中的文件以外的东西,即类本身,我可以通过将-otherMethod更改为+otherMethod来消除该错误。然而,NSObject中实际上有许多方法是按顺序调用的,因此我不希望将EverythSign更改为a+

当从类方法中调用方法时,您应该这样做吗?或者,除了自我,还有别的选择吗

提前感谢您的建议

在实例方法中,self是对当前类的当前实例的引用。顾名思义,类方法是在类本身上调用的,而不是在实例上调用的,因此没有可供self引用的当前实例。在本例中,self指的是当前类

换句话说,在类方法中,调用[self-otherMethod]将调用另一个名为otherMethod的类方法,即用+声明。要调用实例方法,您需要处理对象的实例,要么是传递给类方法的实例,要么是由类方法本身实例化的实例,但您仍然不会使用self引用该实例,而是使用参数或变量名


一般来说,这不应该是一个问题。您需要考虑对象的语义,以及方法是否应该都是类方法,即它们不需要在对象的特定实例上操作,或者它们是否应该是类方法的类方法,如果需要的话,创建一个新的实例,或者您的类方法不应该是类方法。p> 在这个问题上,至少在术语上存在一些混乱,而实际问题并不清楚。希望以下几点能有所帮助

我的理解是self指的是类方法中的文件以外的东西,即类本身

变量self决不是指文件,它总是指调用方法的对象。类方法和实例方法之间的区别在于调用方法的对象的类型

您的示例类:

@implemention MyClass
{
   // any instance variables
}

+ (void)classMethod
{
   NSLog(@"classMethod called");
   [self otherMethod];
}

- (void) otherMethod
{
   NSLog(@"other method called");
}

// ...

@end
定义一个模板,从该模板创建一个类对象,该类对象的类型最终是该类类型的子类,以及零个或多个MyClass类型的实例对象。类对象得到类方法,实例对象得到实例方法,每个对象都得到自己的实例变量集

在代码片段中:

MyClass *anInstance = [MyClass new];
[anInstance otherMethod];
[MyClass classMethod];
然后,一个实例的值(对MyClass类型的对象的引用)被传递给otherMethod,并作为self的值可用。在代码片段中:

MyClass *anInstance = [MyClass new];
[anInstance otherMethod];
[MyClass classMethod];
编译器用对MyClass对象的单个实例的引用(一个对象引用)有效地替换MyClass,并将其传递给classMethod,在那里它作为self。。。换句话说,调用类方法就是调用类对象上的实例方法——机制是相同的

变量self从不引用该文件,也不提供直接访问对象成员(实例或类对象)以外的任何内容的方法

特别是类方法中的self不提供对实例方法或变量的访问,因为它们是实例对象的成员,并且自引用类对象。要在任何地方访问实例方法或变量,都需要实例对象

当从类方法中调用方法时,您应该这样做吗?或者,除了自我,还有别的选择吗

另一种方法是引用实例对象。可能有许多实例,并且没有语言定义的类方法可以使用的默认实例。这一点并不奇怪,因为实例的一个重要特征是它的标识—在典型的应用程序中,有许多具有不同内容、不同类型的数组NSArray,用于不同的目的,每一个个体都与其他个体不同,即具有唯一的身份和方法,这些个体被调用来向/从特定个体实例传递信息

从您的陈述来看,您可能追求的是:

+ (void)classMethodUsingInstance:(MyClass *)someInstance
{
   NSLog(@"classMethod called");
   [someInstance otherMethod];
}
这是因为某些原因,您需要一个可以与特定实例交互的类方法,因此您可以将其作为参数传递。然而,这提出了一个问题,为什么这不仅仅是一个实例方法

有没有更好的方法可以从视图控制器运行大量复杂的代码,而无需将其放入VC?classMethod恰好是一个与使用大量属性和方法的服务器同步的操作。如果可能的话,我不想把它放在调用该方法的VC中,因为VC已经管理了很多。。。[来自评论]

这句话听起来很像你 r classMethod和otherMethod在不同的类中,后者在你的视图控制器类中,前者你不指定它在哪里,我不想把它放在VC中。如果是这种情况,那么上面的大纲可能就是您所需要的,它将VC实例传递给在别处定义的方法。也就是说,您有一些大型复杂的流程在VC上运行,而不是作为VC的一部分,因此您可以在另一个类中定义该流程-作为最适合设计的实例或类方法-并将VC实例传递给它

这不仅是一个标准模型,也是一个基本模型。例如,想想你编写的所有代码,它们使用数组和字典,但不是数组或字典的一部分!,这就引出了一个问题,为什么你会有问题,并首先提出这个问题。。。所以也许你在问别的问题


它不能是实例方法,因为需要从其他视图控制器类调用它。[来自评论]

也许我需要创建名为sharedInstance的类的属性,然后我可以使用[self-sharedInstance].property和[self-sharedInstance]方法访问该类的属性和方法。[来自以下评论]

再加上之前的不在VC评论中,现在听起来像:

您希望在类a上调用方法M; 该方法需要对B的特定实例进行操作; 调用应该来自不同类C中的方法N;和 方法N没有对B的特定实例的引用,而B需要将其调用传递给M。 如果正确意味着是的,那么您可能需要B的共享实例模型


希望这能帮上一点忙,不要搞混了

self通常被当作一个类的实例,我并不是100%发疯,但如果你从一个类方法调用另一个类方法,它可能会起作用。如果你的类方法需要对一个实例执行一些操作,也许可以为它添加一个参数到类方法中?我经常使用self…来获取许多实例变量并调用许多方法。是否无法从类中访问类方法所在的文件?如果您有一个类方法想要调用实例方法,则表明存在更深层次的设计缺陷。只是因为实际上有很多[实例]方法。。。按顺序调用不是不修复此缺陷的原因。坦率地说,抽象地回答这个问题是不可能的,因为正确的解决方案取决于这些不同的方法实际上在做什么?或者属性,或者我必须将它们全部作为参数传入。我有很多这样的实例,所以使用IVAR会很好。但是哪个实例的属性呢?这就是问题所在。MYClass可以有任意数量的实例,也可以没有,而一个类方法不知道您可能引用的是哪个实例,因为它不知道关于这些实例的任何信息。有没有更好的方法可以从视图控制器运行大量复杂的代码,而无需将其放入VC?classMethod恰好是一个与使用大量属性和方法的服务器同步的操作。如果可能的话,我不想把它放在调用该方法的VC中,因为VC已经管理了很多东西,包括单独同步到不同的核心数据实体。所以我会问为什么这是一个类方法。如果它需要访问实例属性,那么它可能应该是一个实例方法。或者这个方法不属于这个类;也许您需要进一步分解对象。很难说没有更多关于对象的细节。它不能是实例方法,因为它需要从不同的视图控制器类调用。另一方面,它管理JSON提要的同步、存储到核心数据以及使用JSON将本地数据上载到服务器的工作非常复杂,如果不访问属性并将代码分解为组件方法,我无法想象这样做。因此,我希望从主方法myMethod中调用otherMethod。我想你是说没有办法用类的方法来分解myMethod或访问属性。谢谢你花时间写这么详细的答案。我打算问一个实际的问题。我应该把理想情况下应该可重用但需要属性才能正常工作的代码放在哪里?太多的属性不能作为参数传递给函数。我试图避免可怕的viewcontroller,它吞噬了MVC的世界版本,在MVC中,您将所有代码放在一个视图控制器中。我从你的答案中得出的结论是,共享实例方法是正确的,事实上,这就是我要做的。