AppDelegate中的方法和作用简述

本篇文章主要介绍一些UIApplicationDelegate中几个常用的回调方法的调用时机。
以帮助你判断哪些方法倒底放到哪个回调中去实现。

1. – (void)applicationDidFinishLaunching:(UIApplication *)application;
此方法基本已经弃用,改用第2个方法代替。
2. – (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
当应用程序启动时(不包括已在后台的情况下转到前台),调用此回调。launchOptions是启动参数,假如用户通过点击push通知启动的应用,这个参数里会存储一些push通知的信息。

3. – (void)applicationDidBecomeActive:(UIApplication *)application;
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
当应用程序全新启动,或者在后台转到前台,完全激活时,都会调用这个方法。如果应用程序是以前运行在后台,这时可以选择刷新用户界面。

4. – (void)applicationWillResignActive:(UIApplication *)application;
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
当应用从活动状态主动到非活动状态的应用程序时会调用这个方法。这可导致产生某些类型的临时中断(如传入电话呼叫或SMS消息)。或者当用户退出应用程序,它开始过渡到的背景状态。使用此方法可以暂停正在进行的任务,禁用定时器,降低OpenGL ES的帧速率。游戏应该使用这种方法来暂停游戏。
调用时机可能有以下几种:锁屏,按HOME键,下接状态栏,双击HOME键弹出低栏,等情况。

5. – (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
// Will be deprecated at some point, please replace with application:openURL:sourceApplication:annotation:
这个方法已不再支持,可能会在以后某个版本中去掉。建议用下面第6个方法代替

6. – (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
// no equiv. notification. return NO if the application can’t open for some reason
当用户通过其它应用启动本应用时,会回调这个方法,url参数是其它应用调用openURL:方法时传过来的。

7. – (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
// try to clean up as much memory as possible. NeXTStep is to terminate app
当应用可用内存不足时,会调用此方法,在这个方法中,应该尽量去清理可能释放的内存。如果实在不行,可能会被强行退出应用。

8. – (void)applicationWillTerminate:(UIApplication *)application;
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
当应用退出,并且进程即将结束时会调到这个方法,一般很少主动调到,更多是内存不足时是被迫调到的,我们应该在这个方法里做一些数据存储操作。

9. // one of these will be called after calling -registerForRemoteNotifications
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
当客户端注册远程通知时,会回调上面两个方法。
如果成功,则回调第一个,客户端把deviceToken取出来发给服务端,push消息的时候要用。
如果失败了,则回调第二个,可以从error参数中看一下失败原因。
注:注册远程通知使用如下方法:

UIRemoteNotificationType t=UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:t];

10. – (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
当应用在前台运行中,收到远程通知时,会回调这个方法。
当应用在后台状态时,点击push消息启动应用,也会回调这个方法。
11. – (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
当应用收到本地通知时会调这个方法,同上面一个方法类似。
如果在前台运行状态直接调用,如果在后台状态,点击通知启动时,也会回调这个方法
本地通知可见另一篇文章:http://bluevt.org/?p=70

12. – (void)applicationDidEnterBackground:(UIApplication *)application ;
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
当用户从台前状态转入后台时,调用此方法。使用此方法来释放资源共享,保存用户数据,无效计时器,并储存足够的应用程序状态信息的情况下被终止后,将应用 程序恢复到目前的状态。如果您的应用程序支持后台运行,这种方法被调用,否则调用applicationWillTerminate:用户退出。

13. – (void)applicationWillEnterForeground:(UIApplication *)application;
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
当应用在后台状态,将要进行动前台运行状态时,会调用此方法。
如果应用不在后台状态,而是直接启动,则不会回调此方法。

<think> 首先,用户的问题是:“我想了解iOS系统中代理相关的内容,可能包括设置、使用方法、原理等 请问iOS系统代理的设置、使用及原理”。用户提到了代理(delegate),这通常在iOS开发中指的是设计模式中的委托模式。 回顾引用内容: - 引用[1]讨论了iOS程序启动过程,涉及UIApplicationAppDelegate,其中AppDelegate是UIApplication的代理。 - 引用[2]提到了main函数调用UIApplicationMain函数。 - 引用[3]讨论了UIViewController管理状态栏。 - 引用[4]提到了多播代理消息转发,包括respondsToSelector:方法的实现。 用户需求聚焦于iOS代理的设置、使用原理。我需要基于这些引用构建一个清晰的回答。 关键点: - **代理(Delegate)**:在iOS中,代理是一种设计模式,允许一个对象(委托方)将某些任务委托给另一个对象(代理方)。例如,UIApplication委托事件给AppDelegate。 - **设置**:设置代理通常通过属性设置,如app.delegate = myDelegate。 - **使用**:代理用于处理事件、回调等,如AppDelegate处理应用程序的生命周期事件。 - **原理**:涉及Objective-C的消息转发机制(如引用[4]所示),其中respondsToSelector:用于检查代理是否响应某个方法。 回答结构: - **引言**:简述代理的重要性。 - **设置代理**:解释如何设置代理,包括代码示例。 - **使用代理**:描述常见场景,如AppDelegate、UIViewController等。 - **原理**:解释代理的工作原理,包括消息转发。 - **相关问题**:生成相关问题。 确保格式: - 行内数学表达式使用$...$(但这可能不涉及)。 - 独立公式用$$...$$(同样可能不适用)。 - 使用中文。 - 末尾添加引用标识。 没有数学内容,所以专注于文本。 完整回答: 1. **代理概述**:代理是iOS中用于事件处理回调的设计模式。 2. **设置代理**:通常通过属性设置,如UIApplication的delegate属性。 3. **使用代理**:在AppDelegate中处理生命周期事件;在其他类如UITableViewDelegate处理表格事件。 4. **原理**:基于Objective-C的消息转发机制;代理对象必须实现特定方法,并通过respondsToSelector:检查。 5. **代码示例**:引用[4]中的代码。 6. **相关问题**:生成3-5个相关问题。 引用整合: - 引用[1]:程序启动时设置AppDelegate为代理。 - 引用[2]:UIApplicationMain函数设置代理。 - 引用[4]:消息转发原理。 回答结构: - 开头总结。 - 分段详细说明。 - 代码块展示。 - 相关问题。 </think> ### iOS系统代理的设置、使用及原理 在iOS开发中,**代理(Delegate)** 是一种核心的设计模式,用于实现对象之间的通信事件处理。它允许一个对象(委托方)将某些任务或事件委托给另一个对象(代理方),从而解耦代码并提高可扩展性。代理广泛应用于UI组件(如UITableViewDelegate)、应用生命周期管理(如AppDelegate异步事件处理中。下面我将基于引用内容,逐步解释代理的设置、使用方法原理。 #### 1. **代理的设置** 代理的设置通常在对象初始化阶段完成,通过属性赋值实现。设置的关键步骤包括: - **声明代理协议(Protocol)**:代理行为通过协议定义一组可选(optional)或必需(required)的方法。例如,UIApplicationDelegate协议定义了应用生命周期相关方法。 - **指定代理对象**:委托方对象(如UIApplication)通过其delegate属性设置代理对象(如AppDelegate)。 - **示例代码**:在iOS程序启动过程中,UIApplication的代理被设置为AppDelegate实例(见引用[1][2])。 例如,在main函数中,UIApplicationMain函数自动创建UIApplication对象,并设置其代理: ```objectivec int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); // AppDelegate被设置为代理 [^2] } } ``` 这,`NSStringFromClass([AppDelegate class])`指定AppDelegate类作为代理。如果手动设置代理(如无storyboard场景),通常在application:didFinishLaunchingWithOptions:方法中显式赋值: ```objectivec - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = [[ViewController alloc] init]; [self.window makeKeyAndVisible]; application.delegate = self; // 设置UIApplication的代理为当前AppDelegate对象 [^1] return YES; } ``` 关键点:代理设置必须确保代理对象实现了协议方法,否则可能引发运行时错误。 #### 2. **代理的使用** 代理的使用涉及事件响应数据传递,常见场景包括: - **应用生命周期管理**:AppDelegate作为UIApplication的代理,处理系统事件(如启动、进入后台)。例如,application:didFinishLaunchingWithOptions:方法在启动后被调用[^1]。 - **UI组件交互**:如UITableViewDelegate处理表格选择事件,或UIViewControllerDelegate管理视图状态(如状态栏样式,见引用[3])。 - **自定义代理**:开发者可以创建自定义协议,允许对象间通信。例如,一个网络请求类可以将回调委托给视图控制器。 **使用步骤**: 1. **遵循协议**:代理方类声明遵循协议(如`@interface MyViewController : UIViewController <UITableViewDelegate>`)。 2. **实现协议方法**:代理方实现必需方法(如didSelectRowAtIndexPath),可选方法可选实现。 3. **设置代理关系**:委托方设置其delegate属性(如tableView.delegate = self)。 4. **事件触发**:当委托方事件发生时(如用户点击表格行),调用代理方法。 **代码示例**: 以下是一个简单示例,展示如何在UITableView中使用代理: ```objectivec // 委托方:UITableView @interface ViewController : UIViewController <UITableViewDelegate> // 遵循协议 @property (nonatomic, strong) UITableView *tableView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; self.tableView.delegate = self; // 设置代理为当前视图控制器 [self.view addSubview:self.tableView]; } // 代理方法实现(必需) - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"Row selected: %ld", (long)indexPath.row); // 处理点击事件 } @end ``` 关键点:代理方法必须是公共的(在协议中声明),且代理对象需响应方法,否则需通过消息转发处理(见原理部分)[^4]。 #### 3. **代理的原理** 代理的原理基于Objective-C的**消息转发机制**,这是一种动态运行时特性。核心思想是:当对象接收到未实现的消息时,系统会尝试转发给代理对象。 - **消息发送过程**: 1. **方法查找**:运行时检查对象是否实现方法(通过`objc_msgSend`)。 2. **消息转发**:如果未实现,触发消息转发链: - 首先调用`resolveInstanceMethod:`尝试动态添加方法。 - 若失败,调用`forwardingTargetForSelector:`尝试重定向消息到代理对象。 - 最后,`forwardInvocation:`完全转发消息(见引用[4])。 3. **代理响应**:代理对象通过`respondsToSelector:`检查是否能处理该方法(必需实现,以避免崩溃)。 - **关键机制**: - **respondsToSelector:检查**:代理对象必须重写此方法,确保只响应支持的协议方法(引用[4]示例): ```objectivec - (BOOL)respondsToSelector:(SEL)aSelector { if ([super respondsToSelector:aSelector]) { return YES; } else { // 检查自定义协议方法 // 例如,如果代理支持某个可选方法,返回YES return [self.myDelegate respondsToSelector:aSelector]; // 多播代理示例 } } ``` 这保证了代理的透明性,就像继承自委托方一样[^4]。 - **协议的可选性与必需性**:协议方法可以标记为`@optional`或`@required`,编译器在编译时检查必需方法,运行时处理可选方法。 - **性能考虑**:消息转发涉及运行时开销(如方法查找),但iOS优化了常见代理场景(如AppDelegate),使其高效。 原理总结:代理模式依赖Objective-C的动态性,通过协议定义接口消息转发实现解耦。这使得iOS框架如UIKit高度灵活,但也要求开发者正确处理代理关系以避免内存泄露或崩溃[^1][^4]。 #### 注意事项 - **内存管理**:代理通常使用weak引用,防止循环引用(如`@property (weak) id<MyDelegate> delegate;`)。 - **多播代理**:引用[4]提到了多播代理(多个对象共享代理),可通过消息转发实现,但需谨慎处理respondsToSelector:。 - **调试技巧**:如果代理方法未被调用,检查代理设置是否正确,以及代理对象是否实现了协议方法。 代理是iOS开发的基础,理解其设置、使用原理能帮助您构建健壮的应用程序[^1][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值