在Xcode 5.0.2中,我为iPhone创建了一个空白的Detail-Master应用程序。
然后在Main.storyboard中,我用UIWebView替换UILabel,并在DetailViewController.h中将其声明为webView
。
我也会将id *defaultItem
替换为NSDictionary *dict
:
#import <UIKit/UIKit.h>
@interface DetailViewController : UIViewController
@property (strong, nonatomic) NSDictionary *dict;
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end
在MasterViewController.m我硬编码“词典词典”_menu
:
#import "MasterViewController.h"
#import "DetailViewController.h"
static NSString *kLabel = @"label";
static NSString *kAuthUrl = @"auth_url";
@interface MasterViewController () {
NSDictionary *_menu;
NSArray *_keys;
}
@end
@implementation MasterViewController
- (void)awakeFromNib
{
[super awakeFromNib];
_menu = @{
@"FB": @{
kLabel: @"Facebook",
kAuthUrl: @"https://graph.facebook.com/oauth/authorize?",
},
@"GG": @{
kLabel: @"Google+",
kAuthUrl: @"https://accounts.google.com/o/oauth2/auth?",
},
@"MR": @{
kLabel: @"Mail.ru",
kAuthUrl: @"https://connect.mail.ru/oauth/authorize?",
},
@"OK": @{
kLabel: @"Odnoklassniki",
kAuthUrl: @"http://www.odnoklassniki.ru/oauth/authorize?",
},
@"VK": @{
kLabel: @"VKontakte",
kAuthUrl: @"http://oauth.vk.com/authorize?",
},
};
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _keys.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
NSString *key = _keys[indexPath.row];
NSString *label = _menu[key][kLabel];
cell.textLabel.text = label;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *key = _keys[indexPath.row];
NSDictionary *dict = _menu[key];
[[segue destinationViewController] setDetailItem:dict]; // XXX the error line
}
}
@end
最后在DetailViewController.m我尝试接受传递的NSDictionary dict
并在webView
中加载网址:
#import "DetailViewController.h"
static NSString *kLabel = @"label";
static NSString *kAuthUrl = @"auth_url";
@interface DetailViewController ()
- (void)configureView;
@end
@implementation DetailViewController
#pragma mark - Managing the detail item
- (void)setDetailItem:(NSDictionary*)newDict
{
if (_dict != newDict) {
_dict = newDict;
[self configureView];
}
}
- (void)configureView
{
if (_dict) {
NSURL *url = [NSURL URLWithString:_dict[kAuthUrl]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView loadRequest:request];
}
}
@end
不幸的是我在Xcode中遇到了编译时错误:
MasterViewController.m:没有已知的选择器'setDetailItem:'
的实例方法
这一行:
[[segue destinationViewController] setDetailItem:dict];
为什么会这样?
UIStoryboardSegue类的destinationViewController属性被声明为类型id
,它不应该接受任何选择器吗?
答案 0 :(得分:2)
编译时错误是因为您既没有在DetailViewController.h
文件中声明该选择器,也没有使用NSDictionary
的名称声明*detailItem
的任何属性。
当您通过
申报财产时@property (strong, nonatomic) NSDictionary *detailItem;
,编译器会自动生成一个setter方法,你可以覆盖
- (void)setDetailItem:(NSDictionary*)detailItem{
}
如果您要将自己的财产设为dict
,请尝试-(void)setDict:(NSDictionary*)dict{}
查看Apple文档中有关属性的详情,或浏览this等链接。
答案 1 :(得分:1)
问题在于编译器点击
[[segue destinationViewController] setDetailItem:dict];
它不知道声明setDetailItem:
的任何类如果找到声明为id
的对象,它将搜索所有它已知的匹配选择器使用声明,如果找不到,它会发出你看到的错误。
您需要确保将声明属性(或方法)setDetailItem:
的类的头文件导入.m
文件。然后它将编译。