方法参数没有类型?

时间:2013-03-06 20:39:24

标签: objective-c

我在这做什么?方法参数可以是无类型的吗?

在最近一个工作正常的项目中,App已经在商店中 - 到目前为止没有问题,我在.h文件中执行了以下操作:

@property (strong, nonatomic) NSManagedObject          *myPerson;
- (HKPersonPicker*) initWithPerson:person;
- (HKPersonPicker*) initWithPerson:person delegate:(id <HKPersonPickerDelegate>)delegate;

我的意思是这样做,但没有:

- (HKPersonPicker*) initWithPerson:(NSManagedObject*)person;
- (HKPersonPicker*) initWithPerson:(NSManagedObject*)person delegate:(id <HKPersonPickerDelegate>)delegate;

.m文件的相应部分:

- (HKPersonPicker*) initWithPerson:person
{
    self = [super init];
    if(self){
        self.myPerson = person;
    }
    return (self);
}

- (HKPersonPicker*) initWithPerson:person delegate:(id <HKPersonPickerDelegate>)delegate
{
    self = [self initWithPerson:person];
    if(self){
        self.delegate = delegate;
    }
    return (self);
}

正如您所看到的,我没有对此人物对象做任何特殊处理,只是将其分配给属性myPerson。由于我没有调用任何对象的方法或访问其数据,因此编译器不需要知道有关该对象的任何信息。但是从编译器的角度来看它是什么呢?输入ID?什么?有没有默认类型?

如你所见,我没有任何实际问题。我只是好奇。希望这个问题不会破坏任何SO规则。

3 个答案:

答案 0 :(得分:3)

使用C时,默认类型为int,但使用Objective-C时为id

答案 1 :(得分:2)

方法中缺少类型声明默认为id。在IIRC中,您可以在Apple的运行时库中看到大量没有返回类型的方法。

答案 2 :(得分:2)

你正在做的事情没有明确的问题,但它并不是真正的犹太人。为了清晰起见,你仍然应该有一个类型声明,并保持良好和一致的Cocoa代码样式。

所以它应该是这样的:

- (GSPersonPicker*) initWithPerson:(id)person;

你应该真正改变财产声明:

@property (strong, nonatomic) id *myPerson;

如果没有更改,那么您的代码会令人困惑。您知道将要进入的类型。因此,让编译器通过使用类型帮助您处理有意义的警告/错误。您也应该使用“HKPerson”类型或任何您命名实体的类型,因此编译器认为您无法传入“HKPlace”(它们都是“id”和“NSManagedObject”类型',这对你没有好处)

更重要的是,除非有理由,否则不应使用动态类型(id)。编译器可以帮助您。错误和警告是你的朋友,他们告诉你搞砸了,而不是计算机。当你使用'id'时,编译器就会去,哦,任何东西都可以进入这里!!! 并且它不会检测到你发送该方法的类型会破坏所有内容的错误。

现在让我们说你将使用多态。 IE,让我们为多个类声明一个通用协议,它定义了我们的人:

@protocol GSPerson
-(NSUInteger)age;
@end

所以现在让我们定义几个类,并让他们订阅协议(胡萝卜 markdown之间的GSPerson就是杀了我atm lol ):

#import "GSPerson.h"
@interface GSSpecialPerson <GSPerson>
// code
@end

#import "GSPerson.h"
@interface GSWeirdPerson <GSPerson>
// code
@end

然后让我们重新定义我们的方法签名以遵守协议:

- (GSPersonPicker*) initWithPerson:(id<GSPerson>)person;

我们的财产声明:

@property (strong, nonatomic) id <GSPerson> *myPerson;

现在编译器知道我传入该方法的任何内容都应符合我上面定义的GSPerson协议(即他们需要一个返回人员年龄的方法)。如果我尝试传递任何其他内容,它将抛出编译器警告,这很好。

更好的是,如果他们缺少必要的方法,它会在你的多态类上发出警告。