【问题标题】:iOS - Linker Error, Duplicate SymboliOS - 链接器错误,重复符号
【发布时间】:2012-04-10 12:33:05
【问题描述】:

我在尝试编译时似乎出错了,它似乎直接指向两个文件..MenuViewController 和 FirstTopViewController。我认为这与我的导入有关,因为它们每个都在导入另一个,但是错误是引用了我的 Building 对象,该对象几乎没有在其中使用。另外,出现 clang 错误,如何使用 -v 来查看调用?

错误:

ld: duplicate symbol _OBJC_CLASS_$_Building in /Users/alexmuller/Library/Developer/Xcode/DerivedData/ECSlidingViewController-gjxwxiwumgohyehiawnlamggzmop/Build/Intermediates/ECSlidingViewController.build/Debug-iphonesimulator/ECSlidingViewController.build/Objects-normal/i386/FirstTopViewController.o and /Users/alexmuller/Library/Developer/Xcode/DerivedData/ECSlidingViewController-gjxwxiwumgohyehiawnlamggzmop/Build/Intermediates/ECSlidingViewController.build/Debug-iphonesimulator/ECSlidingViewController.build/Objects-normal/i386/MenuViewController.o for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

FirstTopViewController.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "ECSlidingViewController.h"
#import "MenuViewController.h"
#import "TimesViewController.h"
#import "BuildingViewController.h"
#import "BuildingAnnotation.h"
#import <MapKit/MapKit.h>

@class BuildingViewController;

@interface FirstTopViewController : UIViewController <MKMapViewDelegate> {
    IBOutlet MKMapView *_map;
    BuildingViewController *buildingVC;
    BuildingAnnotation *buildAnnotation;
}

@property (nonatomic, strong) MKMapView *map;

- (IBAction)revealMenu:(id)sender;
- (IBAction)revealTimes:(id)sender;
- (void)loadBuilding:(Building *)building;

@end

FirstTopViewController.m

#import "FirstTopViewController.h"

@implementation FirstTopViewController

@synthesize map = _map;

- (void)viewDidLoad {

    buildingVC = (BuildingViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"BuildingList"];
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated
{
    [(UIView *)[self.view viewWithTag:10] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"RedWithNoise"]]];
    [super viewWillAppear:animated];
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"toolbar"] forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setTitleTextAttributes:
     [NSDictionary dictionaryWithObjectsAndKeys:
      [UIColor colorWithRed:204.0/255.0 green:204.0/255.0 blue:102.0/255.0 alpha:1.0], 
      UITextAttributeTextColor, 
      [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8], 
      UITextAttributeTextShadowColor, 
      [NSValue valueWithUIOffset:UIOffsetMake(0, -1)], 
      UITextAttributeTextShadowOffset, 
      [UIFont fontWithName:@"AGaramondPro-Regular" size:23.0], 
      UITextAttributeFont, 
      nil]];
    self.view.layer.shadowOffset = CGSizeZero;
    self.view.layer.shadowOpacity = 0.75f;
    self.view.layer.shadowRadius = 10.0f;
    self.view.layer.shadowColor = [UIColor blackColor].CGColor;
    self.view.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.view.layer.bounds].CGPath;
    self.view.clipsToBounds = NO;

    MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(30.451667, -84.268533), 16090.344, 16090.344);
    viewRegion = [_map regionThatFits:viewRegion];
    [_map setRegion:viewRegion animated:YES];

    if (![self.slidingViewController.underLeftViewController isKindOfClass:[MenuViewController class]]) {
        self.slidingViewController.underLeftViewController  = [self.storyboard instantiateViewControllerWithIdentifier:@"Menu"];
    }

    if (![self.slidingViewController.underRightViewController isKindOfClass:[TimesViewController class]]) {
        self.slidingViewController.underRightViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"Times"];
    }

    [self.view addGestureRecognizer:self.slidingViewController.panGesture];


}

- (void)loadBuilding:(Building *)building {
    if (buildingVC.buildingSelected) {
        if (buildAnnotation != nil) {
            [_map removeAnnotation:buildAnnotation];
        }
        NSLog(@"%@", building.getName);
        buildAnnotation = [[BuildingAnnotation alloc] initWithCoordinate:building.getLocation.coordinate withName:building.getName withAddress:building.getAddress];
        [_map setCenterCoordinate:buildAnnotation.coordinate animated:YES];
        [_map addAnnotation:buildAnnotation];
    }
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
  self.view.layer.shadowPath = nil;
  self.view.layer.shouldRasterize = YES;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
  self.view.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.view.layer.bounds].CGPath;
  self.view.layer.shouldRasterize = NO;
}

- (IBAction)revealMenu:(id)sender
{
  [self.slidingViewController anchorTopViewTo:ECRight];
}

- (IBAction)revealTimes:(id)sender {
    [self.slidingViewController anchorTopViewTo:ECLeft];
}

@end

MenuViewController.h

#import <UIKit/UIKit.h>
#import "ECSlidingViewController.h"
#import "FirstTopViewController.h"
#import "TimesViewController.h"

@interface MenuViewController : UIViewController <UITableViewDataSource, UITabBarControllerDelegate> {
    NSIndexPath *selectedIndex;
}

@end

MenuViewController.m

#import "MenuViewController.h"

typedef enum {
    ENGINEERING,
    GARNET,
    GOLD,
    HERITAGE,
    NIGHT,
    OSCEOLA,
    RENEGADE,
    TOMAHAWK
} RouteName;


@interface MenuViewController()
@property (nonatomic, strong) NSArray *menuItems;
@property (nonatomic, strong) NSArray *optionItems;
@property (nonatomic, strong) NSArray *arrayItems;

- (UIImage *)determineActiveRoute:(RouteName)route;
@end

@implementation MenuViewController
@synthesize menuItems, optionItems, arrayItems;

- (void)awakeFromNib
{

    self.menuItems = [NSArray arrayWithObjects:@"Engineering", @"Garnet", @"Gold", @"Heritage Grove", @"Night Nole", @"Osceola", @"Renegade", @"Tomahawk", nil];
    self.optionItems = [NSArray arrayWithObjects:@"Buildings", @"Directions", nil];
    self.arrayItems = [NSArray arrayWithObjects:self.menuItems, self.optionItems, nil];
}

- (void)viewDidLoad
{
  [super viewDidLoad];
  [self.slidingViewController setAnchorRightRevealAmount:200.0f];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex
{
  return [[self.arrayItems objectAtIndex:sectionIndex] count];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [self.arrayItems count];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 35;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *sectionView = [[UIView alloc] init];
    [sectionView sizeToFit];
    sectionView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"navCellDivider"]];
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 100, 20)];
    label.textColor = [UIColor grayColor];
    label.backgroundColor = [UIColor clearColor];
    label.font = [UIFont fontWithName:@"AGaramondPro-Regular" size:12.0];
    if(section == 0)
        label.text = @"BUS ROUTES";
    else
        label.text = @"OTHER OPTIONS";
    [sectionView addSubview:label];
    return sectionView;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UILabel *label;
    UIImageView *imageView;
    NSString *cellIdentifier = @"MenuItemCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

    }
    UIView *selectedView = [[UIView alloc] initWithFrame:cell.frame];
    selectedView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"navCellBackgroundSelected"]];
    cell.selectedBackgroundView = selectedView;
    cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"navCellBackground"]];
    label = (UILabel *)[cell.contentView viewWithTag:100];
    label.font = [UIFont fontWithName:@"AGaramondPro-Regular" size:15.0];
    label.text = [[self.arrayItems objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    imageView = (UIImageView *)[cell.contentView viewWithTag:101];
    if (indexPath.section == 0) {
        [imageView setImage:[self determineActiveRoute:indexPath.row]];
    } else {
        if (indexPath.row == 0) {
            [imageView setImage:[UIImage imageNamed:@"building"]];
        } else {
            [imageView setImage:[UIImage imageNamed:@"60-signpost"]];
        }
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    /* Type cast view as a First Top to make it easier to read. Do switch to select correct route,
        then modify map afterwards to load up correct route.
     TimesViewController can be set to the corresponding times when selected
     */
    FirstTopViewController *mapViewController = (FirstTopViewController *)self.slidingViewController.topViewController;
    TimesViewController *timesViewController = (TimesViewController *)self.slidingViewController.underRightViewController;

    if (indexPath.section == 0) {
        selectedIndex = indexPath;
        switch (indexPath.row) {
            case ENGINEERING:
                NSLog(@"Engineering Selected\n");
                timesViewController.times.text = @"Engineering";
                break;
            case GARNET:
                NSLog(@"Garnet Selected\n");
                timesViewController.times.text = @"Garnet";
                break;
            case GOLD:
                NSLog(@"Gold Selected\n");
                timesViewController.times.text = @"Gold";
                break;
            case HERITAGE:
                NSLog(@"Heritage Grove Selected\n");
                timesViewController.times.text = @"Heritage Grove";
                break;
            case NIGHT:
                NSLog(@"Night Nole Selected\n");
                timesViewController.times.text = @"Night Nole";
                break;
            case OSCEOLA:
                NSLog(@"Osceola Selected\n");
                timesViewController.times.text = @"Osceola";
                break;
            case RENEGADE:
                NSLog(@"Renegade Selected\n");
                timesViewController.times.text = @"Renegade";
                break;
            case TOMAHAWK:
                NSLog(@"Tomahawk Selected\n");
                timesViewController.times.text = @"Tomahawk";
                break;
            default:
                break;
        }
    } else {
        if (indexPath.row == 0) {
            BuildingViewController *buildings = [self.storyboard instantiateViewControllerWithIdentifier:@"BuildingList"];
            buildings.userLoc = [[CLLocation alloc] initWithLatitude:mapViewController.map.userLocation.coordinate.latitude longitude:mapViewController.map.userLocation.coordinate.longitude];

            [self presentModalViewController:buildings animated:YES];
        }
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
        [tableView selectRowAtIndexPath:selectedIndex animated:YES scrollPosition:UITableViewScrollPositionNone];
    }
    [self.slidingViewController anchorTopViewTo:ECRight animations:nil onComplete:^{
        [self.slidingViewController resetTopView];
    }];
}

- (UIImage *)determineActiveRoute:(RouteName)route {
    NSCalendar *gregorianCalender = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [gregorianCalender components:NSHourCalendarUnit fromDate:[NSDate date]];
    switch (route) {
        case ENGINEERING:
            if ([components day] % 7 == 2) {
                if (([components hour] >= 7) && ([components hour] < 17)) {
                    return [UIImage imageNamed:@"green"];
                } else {
                    return [UIImage imageNamed:@"red"];
                }
            } else if (([components day] % 7 == 3) || ([components day] % 7 == 4)) {
                return [UIImage imageNamed:@"red"];
            } else {
                //Weekday
                if (([components hour] >= 7) && ([components hour] < 19)) {
                    return [UIImage imageNamed:@"green"];
                } else {
                    return [UIImage imageNamed:@"red"];
                }
            }
            break;
        case GARNET:
        case GOLD:
        case HERITAGE:
            if ((([components day] % 7 <= 3) || ([components day] % 7 >= 5)) &&
                (([components hour] >= 7) && ([components hour] <= 19))) {
                return [UIImage imageNamed:@"green"];
            } else {
                return [UIImage imageNamed:@"red"];
            }
            break;
        case NIGHT:
            if ((([components day] % 7 == 6) || ([components day] % 7 <= 3)) &&
                (([components hour] >= 22.5) || ([components hour] <= 3))) {
                return [UIImage imageNamed:@"green"];
            } else {
                return [UIImage imageNamed:@"red"];
            }
            break;
        case OSCEOLA:
        case RENEGADE:
        case TOMAHAWK:
            if ((([components day] % 7 <= 3) || ([components day] % 7 >= 5)) &&
                (([components hour] >= 7) && ([components hour] <= 19))) {
                return [UIImage imageNamed:@"green"];
            } else {
                return [UIImage imageNamed:@"red"];
            }
            break;
    }
}

@end

【问题讨论】:

  • 重复符号意味着您的项目或编译列表中有两个名为“Builder”的类。
  • 我有 Building.h、BuildingAnnotation.h 和 BuildingViewController.m/h。有没有办法清除编译列表并让 Xcode 重新生成它?
  • 清除您的编译列表,然后当您添加所有内容时,搜索术语“.m”(不带引号),并突出显示每个 .m 文件。然后点击添加。
  • 这个“编译列表”在哪里?您是指构建阶段下的编译源吗?
  • @Muller 这正是我所指的。至于托马斯的评论,我会先解决这个问题。

标签: iphone objective-c ios linker duplicates


【解决方案1】:

检查您是否未将 .m 文件导入应为 .h 文件的位置。呵呵!

【讨论】:

  • 太棒了!我快疯了,永远不会仔细观察这个
【解决方案2】:

根据您的要求:

从编译源中删除所有类,然后单击 + 按钮并搜索术语“.m”。突出显示每个班级,然后单击添加。再次构建并运行。

【讨论】:

  • iAnum 检查@implementation 行的名称是否正确
  • 我能够将源代码编译到抱怨重复符号的特定文件中。删除它并重新添加它并且它工作。基本上与这个答案相同,而不是轰炸整个事情。
【解决方案3】:

将具有多个 *.a 文件的第三方库导入到我的 IOS 项目时,我遇到了类似的错误。 在我的情况下,删除“-all_load”链接器标志解决了这个问题。

【讨论】:

  • 这消除了我的大部分重复。还剩 4 个。
【解决方案4】:

不确定,但可能有几件事。

  1. 我注意到这两个类似乎都没有导入 Building.h,所以我的第一个想法是编译器不知道从哪里获取此类的信息。需要添加#import 吗?

  2. 接下来我通常会尽量避免让两个类相互导入。编译器在尝试确定编译它们的顺序时可能会遇到问题。您可能需要将其中一个更改为使用 @class ... 而不是 #import ...,以便编译器将其保留到运行时解析类。

  3. 你终于洗干净了吗?有时在进行大量重构时,旧的类定义会留在构建目录中,并可能导致此类问题。

【讨论】:

    【解决方案5】:

    删除文件并选择“删除参考”。将文件再次拖回项目中,应该没问题。这对我有用。

    【讨论】:

      【解决方案6】:

      对我来说造成这种情况的问题是我复制了一个 m 文件,但没有重命名@implementation。确保您没有重复的 @implementation 声明。

      【讨论】:

        【解决方案7】:

        我遇到了这个问题,因为ICMGameDemoCMGameSDK 都将该.m 文件添加到compile sources 面板中,我删除了ICMGameDemo 并重新构建了问题走了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-07
          • 1970-01-01
          • 2011-02-26
          • 2014-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多