2011-04-27 105 views
0

我目前正在学Objective C,并且在这个过程中我做了下面这个愚蠢的小程序。该程序编译良好 - 但我收到警告“多个方法命名'-setName:'找到”。多种方法警告

我只接口并实现了一次该方法。

这个警告是什么意思,我该如何纠正?

#import <Foundation/Foundation.h> 

// these are the three yoga-exercises we can perform 

typedef enum { 
    kCobra, 
    kUniversal, 
    kDog 
} ExerciseName; 

// translating our variables into human 

NSString *nameExercise (ExerciseName nameExercise) 
{ 
    switch (nameExercise) { 
     case kCobra: 
      return @"Cobra Pose"; 
      break; 
     case kUniversal: 
      return @"Universal Stretch"; 
      break; 
     case kDog: 
      return @"Dog Pose"; 
      break; 
    } 

    return @"no clue!"; 

} // nameExercise 


@interface Exercise : NSObject 
{ 
    ExerciseName name; 
} 

-(void) setName: (ExerciseName) name; 
-(void) exerciseDo; 

@end 


@implementation Exercise 

-(void) setName: (ExerciseName) n { 
    name = n; 
} // setName 

-(void) exerciseDo { 
    NSLog(@"Exercise: %@", 
      nameExercise(name)); 
} 

@end 


void executeExercises(id exercises[], int count) { 

    int i; 

    for(i=0; i<count; i++) { 
     id exercise = exercises[i]; 
     [exercise exerciseDo]; 
    } 
} 

int main (int argc, const char * argv[]) { 

    id exercises[1]; 

    exercises[0] = [Exercise new]; // initiating an object of class Exercise 
    [exercises[0] setName:kDog]; 

    executeExercises(exercises, 1); 

    return 0; 

} //main 

回答

5

消息的意思是,有跟在翻译名称setName:多个选择(即,它宣布至少在其他地方之间的所有包括标题)。编译器可能会选择错误的选择器(这可能会导致未定义的行为)。

通常可以纠正使用以下方法中的一个(或更多)的问题:

1)的方法命名为唯一的名称:例如setExerciseName可能没问题,如果没有在其他翻译中使用。

2)匹配另一个选择器的签名。例如setName:(NSString *)name

3)使用类型安全:

Exercise * ex = [Exercise new]; 
[ex setName:kCobra]; 

4)转换的变量的类型:[(Exercise*)exercise setName:kCobra];

5)恢复用一个新的变量类型:Exercise * ex = exercise;

既然你有声明var为id,你已经擦除了类型,这意味着对象可以响应任何可见的选择器。一般而言,除非真正有必要,否则不应以此方式擦除类型。

最好的方法我看到的是在1和3的组合:

[ex setExerciseName:kCobra]; 
+2

1。以这种方式思考......如果从现在开始的六个月内,你从未见过的人必须阅读你的代码,那么代码的哪一行才会最有意义,并让读者最理解你的意图? – bbum 2011-04-27 06:45:29