应用程序在没有协议功能的情况下编译 - 为什么?

App compiles WITHOUT protocol functions - why?

初学者 swift 所以请温柔点

我正在使用 XCode 提供的 Master-Detail 示例中的 AppDelegate.swift 文件。 Appdelegate 文件有第一行

class AppDelegate: UIResponder, UIApplicationDelegate {

我的理解是 AppDelegate 是 UIResponder 的子class 并且符合 UIApplicationDelegate 协议

遵守 UIApplicationDelegate 协议意味着,据我所知,它必须具有以下方法:

applicationDidBecomeActive:
applicationWillResignActive:
applicationDidEnterBackground:
applicationWillEnterForeground:
applicationWillTerminate:

但是,当我删除所有这些应用程序仍然可以编译。这是否意味着这些方法是可选的?如果是这样,拥有该协议的价值是什么?

这些方法是可选的。其价值在于,无论谁采用该协议,都可以只实现选定的方法(或 none,或全部),而不会留下不需要的方法的空实现。

持有委托的人现在负责检查委托是否实现了某些方法并相应地执行它们。

将协议中的可选方法更像是 public 接口的抽象。假设您有一些带有很多方法和属性的 ClassA。但是,您只使用 method1 和 property3,因为在这种情况下这就是您所需要的。然而,对于其他事情,您可能需要 method2 和 property1 等。

使用委托模式,您不关心谁是委托人。但是委托需要知道它有什么能力。

所有方法都是可选的查看UIApplicationDelegate协议的定义,你可以通过+点击class名称进入定义,这是UIApplicationDelegate

protocol UIApplicationDelegate : NSObjectProtocol {

    optional func applicationDidFinishLaunching(application: UIApplication)
    @availability(iOS, introduced=6.0)
    optional func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
    @availability(iOS, introduced=3.0)
    optional func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool

    optional func applicationDidBecomeActive(application: UIApplication)
    optional func applicationWillResignActive(application: UIApplication)
    optional func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool // Will be deprecated at some point, please replace with application:openURL:sourceApplication:annotation:
    @availability(iOS, introduced=4.2)
    optional func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool // no equiv. notification. return NO if the application can't open for some reason

    optional func applicationDidReceiveMemoryWarning(application: UIApplication) // try to clean up as much memory as possible. next step is to terminate app
    optional func applicationWillTerminate(application: UIApplication)
    optional func applicationSignificantTimeChange(application: UIApplication) // midnight, carrier time update, daylight savings time change

    optional func application(application: UIApplication, willChangeStatusBarOrientation newStatusBarOrientation: UIInterfaceOrientation, duration: NSTimeInterval)
    optional func application(application: UIApplication, didChangeStatusBarOrientation oldStatusBarOrientation: UIInterfaceOrientation)

    optional func application(application: UIApplication, willChangeStatusBarFrame newStatusBarFrame: CGRect) // in screen coordinates
    optional func application(application: UIApplication, didChangeStatusBarFrame oldStatusBarFrame: CGRect)

    // This callback will be made upon calling -[UIApplication registerUserNotificationSettings:]. The settings the user has granted to the application will be passed in as the second argument.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings)

    @availability(iOS, introduced=3.0)
    optional func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)

    @availability(iOS, introduced=3.0)
    optional func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError)

    @availability(iOS, introduced=3.0)
    optional func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])

    @availability(iOS, introduced=4.0)
    optional func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification)

    // Called when your app has been activated by the user selecting an action from a local notification.
    // A nil action identifier indicates the default action.
    // You should call the completion handler as soon as you've finished handling the action.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void)

    // Called when your app has been activated by the user selecting an action from a remote notification.
    // A nil action identifier indicates the default action.
    // You should call the completion handler as soon as you've finished handling the action.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void)

    /*! This delegate method offers an opportunity for applications with the "remote-notification" background mode to fetch appropriate new data in response to an incoming remote notification. You should call the fetchCompletionHandler as soon as you're finished performing that operation, so the system can accurately estimate its power and data cost.

     This method will be invoked even if the application was launched or resumed because of the remote notification. The respective delegate methods will be invoked first. Note that this behavior is in contrast to application:didReceiveRemoteNotification:, which is not called in those cases, and which will not be invoked if this method is implemented. !*/
    @availability(iOS, introduced=7.0)
    optional func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)

    /// Applications with the "fetch" background mode may be given opportunities to fetch updated content in the background or when it is convenient for the system. This method will be called in these situations. You should call the fetchCompletionHandler as soon as you're finished performing that operation, so the system can accurately estimate its power and data cost.
    @availability(iOS, introduced=7.0)
    optional func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)

    // Applications using an NSURLSession with a background configuration may be launched or resumed in the background in order to handle the
    // completion of tasks in that session, or to handle authentication. This method will be called with the identifier of the session needing
    // attention. Once a session has been created from a configuration object with that identifier, the session's delegate will begin receiving
    // callbacks. If such a session has already been created (if the app is being resumed, for instance), then the delegate will start receiving
    // callbacks without any action by the application. You should call the completionHandler as soon as you're finished handling the callbacks.
    @availability(iOS, introduced=7.0)
    optional func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)

    @availability(iOS, introduced=8.2)
    optional func application(application: UIApplication, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]?, reply: (([NSObject : AnyObject]!) -> Void)!)

    @availability(iOS, introduced=4.0)
    optional func applicationDidEnterBackground(application: UIApplication)
    @availability(iOS, introduced=4.0)
    optional func applicationWillEnterForeground(application: UIApplication)

    @availability(iOS, introduced=4.0)
    optional func applicationProtectedDataWillBecomeUnavailable(application: UIApplication)
    @availability(iOS, introduced=4.0)
    optional func applicationProtectedDataDidBecomeAvailable(application: UIApplication)

    @availability(iOS, introduced=5.0)
    optional var window: UIWindow? { get set }

    @availability(iOS, introduced=6.0)
    optional func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int

    // Applications may reject specific types of extensions based on the extension point identifier.
    // Constants representing common extension point identifiers are provided further down.
    // If unimplemented, the default behavior is to allow the extension point identifier.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: String) -> Bool

    @availability(iOS, introduced=6.0)
    optional func application(application: UIApplication, viewControllerWithRestorationIdentifierPath identifierComponents: [AnyObject], coder: NSCoder) -> UIViewController?
    @availability(iOS, introduced=6.0)
    optional func application(application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool
    @availability(iOS, introduced=6.0)
    optional func application(application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool
    @availability(iOS, introduced=6.0)
    optional func application(application: UIApplication, willEncodeRestorableStateWithCoder coder: NSCoder)
    @availability(iOS, introduced=6.0)
    optional func application(application: UIApplication, didDecodeRestorableStateWithCoder coder: NSCoder)

    // Called on the main thread as soon as the user indicates they want to continue an activity in your application. The NSUserActivity object may not be available instantly,
    // so use this as an opportunity to show the user that an activity will be continued shortly.
    // For each application:willContinueUserActivityWithType: invocation, you are guaranteed to get exactly one invocation of application:continueUserActivity: on success,
    // or application:didFailToContinueUserActivityWithType:error: if an error was encountered.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool

    // Called on the main thread after the NSUserActivity object is available. Use the data you stored in the NSUserActivity object to re-create what the user was doing.
    // You can create/fetch any restorable objects associated with the user activity, and pass them to the restorationHandler. They will then have the UIResponder restoreUserActivityState: method
    // invoked with the user activity. Invoking the restorationHandler is optional. It may be copied and invoked later, and it will bounce to the main thread to complete its work and call
    // restoreUserActivityState on all objects.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]!) -> Void) -> Bool

    // If the user activity cannot be fetched after willContinueUserActivityWithType is called, this will be called on the main thread when implemented.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, didFailToContinueUserActivityWithType userActivityType: String, error: NSError)

    // This is called on the main thread when a user activity managed by UIKit has been updated. You can use this as a last chance to add additional data to the userActivity.
    @availability(iOS, introduced=8.0)
    optional func application(application: UIApplication, didUpdateUserActivity userActivity: NSUserActivity)
}