课堂问题:我应该在目标c中将自己作为班级使用吗?

时间:2014-05-05 10:16:24

标签: objective-c

哇,我找到了很好的问题。

这是什么?糖果还是大蒜?

有关Objective-C的内容:

是否有任何问题不能在(+) - 类方法中使用'self'作为类?

在课堂深处...

+(NSDate*)dateWithTimeInterval:(NSTimeInterval)interval {
    return [self dateWithTimeIntervalSince1970:interval];
}

Ruby在这里: 例如,在Ruby中,一切都是对象,而类是Class类的对象,并且有一个很好的实践可以依赖于self:

class DateClass 
     # self is DateClass here, inside of class definition, uh
     self.dateWithTimeInterval(interval)
         self.dateWithTimeIntervalSince1970(interval)
     end
end

Perl: 在perl oop深度发现了另一个例子:(感谢this thread

sub new {
    my $proto = shift || die "Must pass a class or object into new()";
    my $class = ref($proto) || $proto;
    bless {}, $class;
}

所以,在Perl和Ruby中,人们总是依赖$class refs

也许Perl代码的例子并不明显,但它始终发生。程序员依赖$ class引用并使用类名。他们也可以用它来调用一些方法:

 my $class = 'Class';
    $class->new();

    Class::->new()

毕竟......

你可以提供哪些陷阱或警告反对使用self作为objective-c中的类?

2 个答案:

答案 0 :(得分:1)

要了解使用selfclass name的利弊,请考虑以下情况:
ANSDate的子类,并实现方法+(NSDate*)dateWithTimeInterval:(NSTimeInterval)interval

BA的子类,并覆盖+dateWithTimeIntervalSince1970:(NSTimeInterval)interval中声明的NSDate方法的实现。

现在让我们考虑+(NSDate*)dateWithTimeInterval:(NSTimeInterval)intervalA方法的两种可能实现:

1。使用self

+(NSDate*)dateWithTimeInterval:(NSTimeInterval)interval {
    return [self dateWithTimeIntervalSince1970:interval];
}

如果运行[B dateWithTimeInterval:interval];,则上面代码中的self类似于B类,并且B方法的预期自定义实现(在类+(NSDate*)dateWithTimeIntervalSince1970:(NSTimeInterval)interval中)将会被称为。

2。直接使用NSDate

+(NSDate*)dateWithTimeInterval:(NSTimeInterval)interval {
    return [NSDate dateWithTimeIntervalSince1970:interval];
}

如果运行[B dateWithTimeInterval:interval];,那么覆盖的实现(在类B中)将被忽略而不是它:NSDate方法的原始实现(在类+(NSDate*)dateWithTimeIntervalSince1970:(NSTimeInterval)interval中)将是调用。这是因为我们直接向NSDate发送消息:[NSDate dateWithTimeIntervalSince1970:interval]; 对于开发人员来说,这种行

出于同样的原因,以这种方式声明方法:

+(instancetype)dateWithTimeInterval:(NSTimeInterval)interval {
    return [self dateWithTimeIntervalSince1970:interval];
}

通过使用instancetype编译器将知道method-initializer返回什么类型的对象。当您致电[B dateWithTimeInterval:interval]时,它会返回实物B但不是NSDate的对象。

答案 1 :(得分:1)

通常情况下,只要可以使用self,当然,有些情况下需要[MyClass class]引用类。几乎所有场景都与继承有关。

例如,类A.

的创建者方法
@implementation A

+ (id)createInstanceWithParam:(NSInteger)param {
   return [[self alloc] initWithParam:param];
}

@end

即使我们创建了子类B,它也能正常工作。但是,如果我们决定实现类集群,那么我们必须按名称引用类:

@implementation SomeDataStructure

+ (id)createInstanceWithType:(NSInteger)type {
    if (type == 0) {
       return [[DataStructureImpl1 alloc] init];
    }
    else if (type == 1) {
       return [[DataStructureImpl2 alloc] init];
    }
}

@end

另一个例子是+initialize

的常见例子
+ (void)initialize {
    if (self == [MyClass class]) {
        ...perform initialization...
    }
}

当然,如果要覆盖方法,那么使用self或使用[MySelf class]可以区分您的覆盖实现和原始实现。虽然super也可以在那里使用。

TLDR: self是首选,但要小心子类/超类。