【问题标题】:how can i specify the UIApplicationDelegate protocol, and only the UIApplicationDelegate protocol?如何指定 UIApplicationDelegate 协议,并且只指定 UIApplicationDelegate 协议?
【发布时间】:2013-12-15 20:51:00
【问题描述】:

Xcode 基于模板生成了这个头文件:

// this file is XYZAppDelegate.h  
#import <UIKit/UIKit.h>
@interface XYZAppDelegate : UIResponder <UIApplicationDelegate>
....
@end

为了让编译器弄清楚 UIApplicationDelegate 是什么,它是如何工作的?
(1) 整个 UIKit 框架 (UIKit.h) 已导入。
(2) UIApplication.hUIKit.h 中指定的众多头文件之一。
(3) UIApplicationDelegate 协议然后在UIApplication.h 中指定。

为了我的理解,我可以写一个:
@interface XYZAppDelegate:UIResponder direct-reference-to-protocol>

也许,比如:
@interface XYZAppDelegate:UIResponder UIKit.UIApplication.UIApplicationDelegate>

【问题讨论】:

  • 不,你不能按照你的要求去做。你为什么想要?它的方式有什么问题?
  • 我正在尝试减少源文件中不必要的信息量。以及,只是弄清楚 obj-c 和 Xcode 是如何工作的。
  • 源文件中有哪些不必要的信息?目前它只有必要的信息。
  • 我不需要超过 100 个不需要的函数声明来引用 UIApplicationDelegate 协议中的函数声明吗?
  • 但这一切都隐藏在头文件中。您的源文件只包含一些需要的 #import 语句。没有必要担心您在 .m 文件中碰巧使用的一些声明是随随便便的。让编译器担心这一点。您无需添加或查看不需要的声明。

标签: objective-c


【解决方案1】:

要在类上指定协议,编译器需要知道它。唯一的方法是指定

@protocol MyProtocol
...
@end

对于类、类别等任何事物也是如此。

编译器与任何 C 编译器一样,逐个文件处理。它可以并且不会记住它在两次运行之间看到的任何内容。这意味着,为了能够知道 MyProtocol 是什么,编译器必须提供与上面类似的协议定义在同一个文件中

因为总是指定一百万次会非常烦人,C 语言的人在几十年前就发现,如果有预处理器指令在指令所在的位置插入特定文件,那就太好了。这就是#include 诞生的时候。

#import#include 基本相同,只是它还会检查文件是否之前已包含,并且不会像#include 那样多次执行。两者都只是获取文件并假装该文件的全部内容将在指令的位置 - 仅此而已。

由于 C 和 Objective-C 都没有框架级别的命名空间,编译器知道的每个符号都可以并且必须通过指定其名称来简单地使用。您可能从 Java(如 System.out.println())或其他编程语言中知道的命名空间的 . 语法之类的东西不存在。

【讨论】:

  • 其实这是更好的答案。声明“必须在同一个文件中”是正在发生的事情的具体细节。我现在完全明白这一点了。谢谢。
【解决方案2】:

你可能想看看这个What is the difference between #import and #include in Objective-C?
当然可以

#import <UIKit/UIApplication.h> 
#import <UIKit/UIResponder.h>

而不是

#import <UIKit/UIKit.h>

但是,我可以看到这种方式的一些缺点。如果 Apple 及时将UIApplicationDelegate 协议声明移动到另一个标头怎么办?如果您的某些文件中需要 10 个 UIKit 类怎么办?你会写吗

#import <UIKit/UIView.h>
#import <UIKit/UIScrollView.h>
#import <UIKit/UIButton.h>
...
#import <UIKit/header_over_9kth.h>

不过,您可以在此处尝试优化导入并发布编译时间报告。如果您能通过此类优化获得更多性能,那将会很有趣

【讨论】:

  • 我认为不会有任何性能提升,因为 UIKit 已经加载到内存中了。
  • 这是个难题。我同意你的观点,不会有性能改进,但我认为真相隐藏在 llvm 和 clang 实现中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2021-10-29
  • 2015-08-10
  • 1970-01-01
  • 2015-11-18
相关资源
最近更新 更多