Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.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返回init中不同类的实例_Objective C_Class_Initialization - Fatal编程技术网

Objective-C返回init中不同类的实例

Objective-C返回init中不同类的实例,objective-c,class,initialization,Objective C,Class,Initialization,在Objective C at init方法中是否可以返回不同类的实例? 我正在上一门课:MyCustomClass。我还有另外两个不同的类,分别称为class1和Class2。我试图实现的是:当我调用[[MyCustomClass alloc]initWithSomeParameters创建Class1或Class2的实例时,这取决于某些条件 MyCustomClass.m: #import "MyCustomClass.h" #import "Class1.h" #import "Class

在Objective C at init方法中是否可以返回不同类的实例? 我正在上一门课:MyCustomClass。我还有另外两个不同的类,分别称为
class1
Class2
。我试图实现的是:当我调用
[[MyCustomClass alloc]initWithSomeParameters
创建
Class1
Class2
的实例时,这取决于某些条件

MyCustomClass.m

#import "MyCustomClass.h"
#import "Class1.h"
#import "Class2.h"

-(id) initWithSomeParameters: (id) params{
  id myClass;
  if (someCondition){
    myClass = [[Class1 alloc] initWithSomeParameters:(id) params];
    [myClass setSomething:something];
  }else{
    myClass = [[Class2 alloc] initWithSomeParameters:(id) params];
    [myClass setSomething:something];
  }
  return myClass;
}
…然后我打电话

id myCustomClass = [[MyCustomClass alloc] initWithSomeParameters:(id) params];

这是一种错误的方法吗?如果是,正确的方法是什么?

这不是一种好方法。最好使用一些帮助类或us factory模式,并为方法提供参数。然后根据参数创建类的对象并返回

在不同类的init方法中创建不同类的对象不是很好的方法

编辑: 如果要根据iOS版本显示UIView或UIAlertView,请执行以下操作

@interface AlertHelper : NSObject
+ (id)getAlert;
@end

///
@implementation AlertHelper
+(id)getAlert{
NSString *version = [[UIDevice currentDevice] systemVersion];
int ver = [version intValue];
if (ver < 7){
//For iOS 6
return something;
}
else{
//for ios 7
return something
}
}
@end
@接口AlertHelper:NSObject
+(id)getAlert;
@结束
///
@实现AlertHelper
+(id)getAlert{
NSString*版本=[[UIDevice currentDevice]系统版本];
int ver=[version intValue];
如果(版本<7){
//对于iOS 6
归还某物;
}
否则{
//对于ios 7
归还某物
}
}
@结束

这不是一个好方法。最好使用一些助手类或us factory模式,并为方法提供参数。然后根据参数创建类的对象并返回

在不同类的init方法中创建不同类的对象不是很好的方法

编辑: 如果要根据iOS版本显示UIView或UIAlertView,请执行以下操作

@interface AlertHelper : NSObject
+ (id)getAlert;
@end

///
@implementation AlertHelper
+(id)getAlert{
NSString *version = [[UIDevice currentDevice] systemVersion];
int ver = [version intValue];
if (ver < 7){
//For iOS 6
return something;
}
else{
//for ios 7
return something
}
}
@end
@接口AlertHelper:NSObject
+(id)getAlert;
@结束
///
@实现AlertHelper
+(id)getAlert{
NSString*版本=[[UIDevice currentDevice]系统版本];
int ver=[version intValue];
如果(版本<7){
//对于iOS 6
归还某物;
}
否则{
//对于ios 7
归还某物
}
}
@结束

您应该制作某种控制器,用于初始化正确的类。您还可以使用类方法实现相同的功能


在genreal中,这个给定的实现是不好的,因为您只需分配一次内存
[MyCustomClass alloc]
,然后在
-(id)initWithSomeParameters:(id)params
您再次分配内存。因此,即使不同的地址也会被重新运行,这与apple指南不同,一些apple类也有这样的行为,但它们这样做是因为进行了优化。但这是错误的。

您应该制作某种控制器,初始化正确的类。您还可以实现相同的功能,即唱课方法


在genreal中,这个给定的实现是不好的,因为您只需分配一次内存
[MyCustomClass alloc]
,然后在
-(id)initWithSomeParameters:(id)params
您再次分配内存。因此,即使是不同的地址也会重新运行,这与apple指南不同,一些apple类也有这样的行为,但它们这样做是因为进行了优化。但这是错误的。

其他一些人提到了这一点,但调用
[[MyClass alloc]init]的结果是错误的
必须始终是
nil
或一种MyClass。它不一定是
MyClass
的一个实例;它的一个后代是可能的,就像
NSArray
NSString
一样。在代码中,此要求如下所示:

MyClass *a = [[MyClass alloc] init];
NSAssert((a==nil) || [a isKindOfClass:[MyClass class]], @"This must always hold true.");
我从未尝试过实现这一点,但它可能必须看起来像这样:

- (id)initAsSubclass:(NSString *)sublcassName
{
    Class c = NSClassFromString(subclassName);
    self = [[c alloc] init];
    if (self) {
        // Do Custom Init Here
    }
    return self;
}
关键是:

  • 不要执行
    [super init]
  • 使用
    +alloc
    创建一个全新的对象
  • 将新创建的对象指定给
    self
  • 如果不使用ARC,请在替换值之前执行
    [self autorelease]
    。(如果当前正在执行代码的对象被解除分配,则可能会导致问题。
    -autorelease
    将延迟该操作,直到本节完成。)

    • 其他一些人已经提到了这一点,但是调用
      [[MyClass alloc]init]的结果是
      必须始终是
      nil
      或一种MyClass。它不一定是
      MyClass
      的一个实例;它的一个后代是可能的,就像
      NSArray
      NSString
      一样。在代码中,此要求如下所示:

      MyClass *a = [[MyClass alloc] init];
      NSAssert((a==nil) || [a isKindOfClass:[MyClass class]], @"This must always hold true.");
      
      我从未尝试过实现这一点,但它可能必须看起来像这样:

      - (id)initAsSubclass:(NSString *)sublcassName
      {
          Class c = NSClassFromString(subclassName);
          self = [[c alloc] init];
          if (self) {
              // Do Custom Init Here
          }
          return self;
      }
      
      关键是:

      • 不要执行
        [super init]
      • 使用
        +alloc
        创建一个全新的对象
      • 将新创建的对象指定给
        self
      • 如果不使用ARC,请在替换值之前执行
        [self autorelease]
        。(如果当前正在执行代码的对象被解除分配,则可能会导致问题。
        -autorelease
        将延迟该操作,直到本节完成。)

      方法如下:

      - (id)initAsSubclass:(NSString *)sublcassName
      {
          Class c = NSClassFromString(subclassName);
          self = [[c alloc] init];
          if (self) {
              // Do Custom Init Here
          }
          return self;
      }
      
      创建基类,如:

      #import "Base.h"
      #import "Class1.h"
      #import "Class2.h"
      
      @implementation Base
      
      + (id)classWithParams:(id)params
      {
           id retVal = nil;    
      
           if (condition_based_on_params_means_creating_class1)
           {
              retVal = [[Class1 alloc] initWithSomeParameters:params];
           }
           else
           {
               retVal = [[Class2 alloc] initWithSomeParameters:params]
           }
      
           return retVal;
      }
      
      @end 
      
      Class1从基继承:

      @interface Class1 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      @interface Class2 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      类2继承自基:

      @interface Class1 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      @interface Class2 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      最终,您将拥有:

      Base* a = [Base classWithParams:yourParams];
      

      方法如下:

      - (id)initAsSubclass:(NSString *)sublcassName
      {
          Class c = NSClassFromString(subclassName);
          self = [[c alloc] init];
          if (self) {
              // Do Custom Init Here
          }
          return self;
      }
      
      创建基类,如:

      #import "Base.h"
      #import "Class1.h"
      #import "Class2.h"
      
      @implementation Base
      
      + (id)classWithParams:(id)params
      {
           id retVal = nil;    
      
           if (condition_based_on_params_means_creating_class1)
           {
              retVal = [[Class1 alloc] initWithSomeParameters:params];
           }
           else
           {
               retVal = [[Class2 alloc] initWithSomeParameters:params]
           }
      
           return retVal;
      }
      
      @end 
      
      Class1从基继承:

      @interface Class1 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      @interface Class2 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      类2继承自基:

      @interface Class1 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      @interface Class2 : Base
      {
      }
      - (id)initWithSomeParameters:(id)parameters;
      @end
      
      最终,您将拥有:

      Base* a = [Base classWithParams:yourParams];
      

      您的
      MyCustomClass
      的子类可能是
      Class 1
      Class 2
      的重复项,谢谢您的快速回答!不,Class1和Class2不是MyCustomClass的子类。Class1是UIAlertView的子类,Class2是UIView的子类。MyCustomClass是NSObject。@AaronBrager是的,但这将是糟糕的类设计……那种逻辑的类不应该在init方法中。@bbum我同意;但这不是该问题的重复。可能的重复是
      Class1
      Class2
      您的
      MyCustomClass
      的子类。谢谢您的快速回答!不,Class1和Class2不是MyCustomClass的子类。Class1是UIAlertView,Class2是UIVie的子类w、 我的