2010-02-08 43 views
1

我在iPhone应用程序中使用http://github.com/facebook/three20。我按照说明将框架包含在我的项目中。我已经验证了两次(在谷歌组和IRC上的人们的建议)。我得到当一些Three20代码试图在UIView的使用编目选择以下错误:从Obj-c Three20库目录中缺少选择器

- [TTSearchTextField ancestorOrSelfWithClass:]:无法识别的选择发送到实例0x3a85ee0'

当我触碰此异常被触发文本字段。

下面是我的踢球者,如果我不给TTSearchTextField指定数据源,它不会触发错误。所以,逻辑上我认为它一定是我的数据源。

  1. 我在我的数据源中的每个函数放置了一个断点。
  2. 运行该程序,如预期的那样调用了init并调用了访问者代表。
  3. 点击文本字段,没有调用我的dataSource并发生运行时异常。

我很难过这个。我以前从未遇到过使用外部库的问题。我可以提供有关项目设置的更多信息,只是询问具体情况,因为那里有相当多的信息。我使用的是创建TTSearchTextField

代码:

// setup Country 
self.searchFieldCountry = [[TTSearchTextField alloc]initWithFrame:CGRectMake(156, 145, 146, 37)]; 
self.searchFieldCountry.borderStyle = UITextBorderStyleRoundedRect; 
self.searchFieldCountry.placeholder = @"Country"; 
self.searchFieldCountry.autocapitalizationType = UITextAutocapitalizationTypeNone; 
OLLocationSearchDataSource *ds = [[OLLocationSearchDataSource alloc]init]; 
self.searchFieldCountry.dataSource = ds; 
[self.view addSubview:self.searchFieldCountry]; 
[ds release]; 

代码为我的数据源:

#import "OLLocation.h" 
#import "AppSession.h" 

@implementation OLLocation 

@synthesize locationData = _locationData; 

@synthesize locationMode,country,region; 

- (NSMutableArray*)delegates { 
    if (!_delegates) { 
     _delegates = TTCreateNonRetainingArray(); 
    } 
    return _delegates; 
} 

- (BOOL)isLoadingMore { 
    return NO; 
} 

- (BOOL)isOutdated { 
    return NO; 
} 

- (BOOL)isLoaded { 
    return !!_AllLocationData; 
} 

- (BOOL)isLoading { 
    return NO; 
} 

- (BOOL)isEmpty { 
    return !_AllLocationData.count; 
} 

- (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more { 
} 

- (void)invalidate:(BOOL)erase { 
} 

- (void)cancel { 
    // cancel a search if possible 
} 

- (void)loadNames { 
    _AllLocationData = [[AppSession getAppSession] getCountries]; 
} 

- (void)search:(NSString*)text { 
    [self cancel]; 

    self.locationData = [NSMutableArray array]; 

    if (text.length) { 
     text = [text lowercaseString]; 
     for (NSString* name in _AllLocationData) { 
      if ([[name lowercaseString] rangeOfString:text].location == 0) { 
       [_locationData addObject:name]; 
      } 
     } 
    } 
} 

- (void)dealloc { 
    [super dealloc]; 
} 

@end 

@implementation OLLocationSearchDataSource 

@synthesize locations = _locations; 

-(id)init { 
    if (self = [super init]) { 
     _locations = [[OLLocation alloc] init]; 
     _locations.locationMode = OLLocationModeCountry; 
     self.model = _locations; 
    } 
    return self; 
} 

-(void)dealloc { 
    TT_RELEASE_SAFELY(_locations); 
    [super dealloc]; 
} 

/////////////////////////////////////////////////////////////////////////////////////////////////// 
// TTTableViewDataSource 

- (void)tableViewDidLoadModel:(UITableView*)tableView { 
    self.items = [NSMutableArray array]; 

    for (NSString* name in _locations.locationData) { 
     TTTableItem* item = [TTTableTextItem itemWithText:name URL:@"http://google.com"]; 
     [_items addObject:item]; 
    } 
} 

- (void)search:(NSString*)text { 
    [_locations search:text]; 
} 

- (NSString*)titleForLoading:(BOOL)reloading { 
    return @"Searching..."; 
} 

- (NSString*)titleForNoData { 
    return @"No names found"; 
} 

@end 

回答

2

我不认为这是您的数据源。 -ancestorOrSelfWithClass:是一种扩展UIView的类别方法,并且在UIViewAdditions.h中添加。您在添加数据源时遇到错误的原因可能是,如果数据源未分配,则无论代码发送-ancestorOrSelfWithClass:消息的可能都不会被调用。

在编译静态库以包含到iPhone应用程序中时,在2.x下,您需要将-ObjC添加到其他链接器标志以确保类别方法已链接到库中。在3.x中,这似乎不能正常工作,所以 - all_load也需要添加到其他链接器标志。

+0

确实。这正是IRC和邮件列表中的人们所建议的。这是一个3.x项目,我在其他链接器标志中同时具有-ObjC和-all_load。还有其他建议吗?我想知道是否有办法确认它实际上在编译时应用这些标志... – jsapara 2010-02-09 03:08:24

+1

我调试了此项目的构建过程,发现它并未在链接上使用-all_load。该项目明确地定义了它,但它没有被应用到我们的任何构建目标中。我进去并将-all_load添加到目标,现在它可以工作。 我回到之前使用Three20的项目,链接器标志在项目中明确定义。我创建了一个新项目并投入了一个快速的Three20 UI小部件,并将链接器标志添加到项目中(而不是目标)。工作得很好,所以在Xcode文件中一定有些奇怪/损坏。无论哪种方式,它都解决了。 – jsapara 2010-02-09 04:51:56