【问题标题】:Why there is no protocol declaration in view controller's header?为什么视图控制器的标头中没有协议声明?
【发布时间】:2014-04-25 04:30:15
【问题描述】:

我正在学习objective-c,并在我的书中找到了以下代码。我有 3 个问题,

  1. 显然,它通过实现两个必需的方法来符合协议,但为什么不在标头中写入<UITableViewDataSource,UITableViewDelegate> 就可以工作?
  2. 它符合哪个协议,UITableViewDataSourceUITableViewDelegate
  3. 为什么没有UITableView.delegate = self

这是代码,

@implementation ItemsViewController

-(instancetype) init
{
    self = [super initWithStyle:UITableViewStylePlain];
    if (self) {
        for (int i = 0; i < 5; i++)
        {
            [[ItemStore sharedStore] creatItem];
        }
    }
    return self;
}
-(instancetype) initWithStyle:(UITableViewStyle)style
{
    return [self init];
}

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[[ItemStore sharedStore] allItems] count];
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *c = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell" forIndexPath:indexPath];
    NSArray *items = [[ItemStore sharedStore] allItems];
    Item *item = [items objectAtIndex:indexPath.row];
    c.textLabel.text = [item description];
    return c;
}

-(void) viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];
}

@end

感谢您帮助理解这一点。

【问题讨论】:

    标签: ios objective-c uitableview delegates datasource


    【解决方案1】:

    1. Obviously it conforms the protocol by implementing two required methods, but why this works without writing '&lt;'UITableViewDataSource,UITableViewDelegate'&gt;' in the header?

    标题中的 '' 只是向编译器表明你想在你的类中实现委托方法。如果您不实现标记为 @required 的委托方法,您将收到警告,但由于大多数委托方法通常是 @optional 您的代码将编译并运行美好的。这并不意味着您不应该在标题中添加代表。

    2. Which protocol it conforms, UITableViewDataSource or UITableViewDelegate?

    默认只需要UITableViewDataSource,必须定义这两个函数

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
    
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    

    3. Why there is no UITableView.delegate = self?

    在那里,检查你的xib 你也从xib 设置了委托。右键UITableView你就明白我的意思了,不设置委托上面的方法都行不通。

    希望这会有所帮助。

    【讨论】:

    • 谢谢!但是当我需要 UITableViewDelegate 协议时呢?我没有使用界面生成器,所以找不到 .xib 文件。
    • @wz366 只需按下命令按钮并点击UITableView 即可找到要实现的UITableViewDelegate 方法。
    【解决方案2】:

    我同意@iphonic,但对于第一点。

    标题中的 '' 指示编译器该类的实例确实响应了该协议。该信息被编译器用作类型匹配的附加信息。例如,当您为表视图设置委托或数据源属性时。

    如果你不在类的头部写'',而你写了类似“tableView.dataSource = self”的东西,那么你会得到警告。当您使用 IB 或 Storyboard 时,您不会编写该设置行。这就是您不必在类接口中包含协议声明的原因。

    【讨论】:

    • 不写tableView.dataSource = self,tableview如何找到它的委托?
    • @wz366 我说“当你使用 IB 或 Storyboard 时”。在 IB 中,存在对象之间的连接。当使用 coder 创建表视图时,它的属性(dataSource、delegate 等)会被初始化。
    • 顺便说一句。如果您在代码中初始化表视图控制器(无 IB 或 SB),则表视图会自动创建为其 tableView 属性,并在控制器上链接为 dataSource 和委托。在这种情况下,编译器不需要做任何事情,也不需要协议声明。
    【解决方案3】:

    ItemsViewController 看起来是 UITableViewControllerUITableViewController 实例是默认的 delegatedatasource,用于包含通过 self.tableView 访问的 UITableView

    因此没有明确标记协议实现&lt;UITableViewDataSource,UITableViewDelegate&gt; 并设置self.tableView.delegate = selfself.tableView.datasource = self

    但是,您可以选择将不同的实例设置为 delegatedatasource,在这种情况下,您需要创建该实例,在其中实现所需的方法并将其分配给 tableView

    希望有帮助!

    【讨论】:

    • 谢谢!当我将不同的实例设置为委托或数据源时,如果该类不是 UITableViewController 的子类,是否需要在该实例的类头中显式声明 ''?
    • @wz366 是的,用已实现的协议标记接口是一个好习惯。
    • @wz366 只要您的类实现委托方法,这不是强制性的。 Xcode 可能会因未标记类而生成警告,但应用程序不应崩溃。
    猜你喜欢
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 2015-11-21
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多