如果使用self,则使用instanceType作为返回值会失败。为什么?

时间:2013-01-07 08:00:03

标签: objective-c clang xcode4.5

static NSMutableDictionary * allTheSingletons;
@implementation BGSuperSingleton

+(instancetype)singleton
{
    return [self singleton1];
}
+(id) singleton1
{
    NSString* className = NSStringFromClass([self class]);

    if (!allTheSingletons)
    {
        allTheSingletons = NSMutableDictionary.dictionary;
    }

    id result = allTheSingletons[className];

    PO(result);
    if (result==nil)
    {
        result = [[[self class] alloc]init];
        allTheSingletons[className]=result;
    }
    return result;
}

BGSuperSingleton应该是所有单身人士的父母。

然后我在其中一个子类中执行:

+(NSPredicate *)withinASquare:(double)distance{
    CLLocation * anchorWeUsed=[self singleton].mapCenterLocation; //Error map center is not of type ID
    return [self withinASquare:distance fromLocation:anchorWeUsed];
}

看起来CLANG不理解单例是+(instancetype)类型,而是认为类型是id。

我错过了什么?

使用self替换MySubSingletonClass(这是在编译时已知的东西)可以正常工作。

有任何解释吗?

1 个答案:

答案 0 :(得分:1)

不确定(以及所有下面只是我的假设)但似乎在编译时编译器不知道[self singleton1]的类。 正如在docs中所说的那样(如果我们也在instancetype上推断出这种行为):

  

...如果该方法的返回类型与其类的类型兼容,则该方法将具有相关的结果类型 ...

即。 singleton1返回一个未知类的对象,singleton也认为它返回与BGSuperSingleton类不兼容的对象(只要它在编译时未知),因此相关的结果魔法不是在这里工作。

对此感兴趣并检查:

+ (NSPredicate*) withinASquare: (double)distance {
    CLLocation* anchorWeUsed = [[self alloc] init].mapCenterLocation; // Error map center is not of type ID
    return [self withinASquare:distance fromLocation:anchorWeUsed];
}

allocinit返回相关的结果类,错误仍然存​​在。帮助的是:

+ (NSPredicate*) withinASquare: (double)distance {
    BGSuperSingleton* bgSuperSingleton = [[self alloc] init]; // class is known at compile time
    CLLocation* anchorWeUsed = bgSuperSingleton.mapCenterLocation; // no error here
    return [self withinASquare:distance fromLocation:anchorWeUsed];
}

我仍然对此感兴趣并希望有人可以批准或纠正我的假设