[UIApplication sharedApplication].delegate 调用全局变量

本文详细解析了UIApplication的概念及其在iOS应用中的作用。介绍了UIApplication作为应用的唯一实例如何被创建和使用,并展示了如何在AppDelegate中定义和使用全局变量。

#UIApplication,顾名思义,代表的是整个应用做的事,因此每个程序只能有一个,系统使用的是单例模式,就是上面的[UIApplication sharedApplication]来得到一个实例。这个单例实例是在系统启动时由main函数里面的UIApplicationMain方法生成,就是每个程序里都有的AppDelegate,它实现了UIApplicationDelegate的Protocol,也就是AppDelegate的一个实例。每次通过[UIApplication sharedApplication]调用的就是它。


----------------------------在AppDelegate.h 中定义全局变量------------------------

@interface AppDelegate : UIResponder <UIApplicationDelegate>{
SinaWeibo * _sinaweibo;

@property (strong,nonatomic) SinaWeibo *sinaweibo;
@end

在AppDelegate.m 文件中 
@implementation AppDelegate

//注意释放
- (void)dealloc
{
[ _sinaweibo release ];


在需要使用的视图控制器中,应用appdelegate
AppDelegate *appDelegate=[[UIApplication sharedApplication] delegate];

 return appDelegate.sinaweibo


------------------------#sharedApplication#----------------------------------------

它里面的实现应该就是这样,返回一个UIApplication实例

static UIApplication * application = nil;

+(UIApplication*) shareApplication{

    if(application == nil){

        application= [[UIApplication alloc]init];

    }

    return application;

}


下面我实现的一个页面调用TABAnimated库实现骨架屏的代码(只有前半部分)与TABAnimated库的说明,现在我想规范这个代码,实现一个TPBSkeletonManager封装这些操作,一个封装TABAnimated库。提供自动生成、自定义样式骨架、默认样式骨架的骨架屏模组,使用和维护便捷,可以传入需要实现骨架屏的view、tableview、collection view,就能返回默认的骨架生成方法。只需要简单命令就能在骨架屏需要展示的时候启动对应的骨架屏,在骨架屏需要消失的时候也是一个明确简单的命令就能关闭骨架屏。 一个页面调用TABAnimated库实现骨架屏的代码: @implementation SDNV6SiteDashboardViewController - (instancetype)init { self = [super init]; if (self) { [self bindDelegate]; } return self; } // 目前直接对加载到Cell的UIView构建骨架屏并按顺序直接画出遮挡 // 对于无法加载识别的自定义view:SDNV6SiteDashboardDensityView *apDensityContainerView无法应用也难以快速修改 - 解决,使用手动方案一 // 对于没有声明在主程序的view:SDNInsightHeadView *headView,其“Wi-Fi Activity”也无法解决 - 尚未解决 - (void)viewDidLoad { // 骨架屏bug:新增页面部署骨架屏不然整体消失速度异常 self.WifiActivityHeadView = [[SDNInsightHeadView alloc] init]; // 正常页面生成 [super viewDidLoad]; [self updatePermission]; [self.tableView layoutIfNeeded]; [self reloadView]; [self omdRegisterForSkipLifeCycleEvent]; // 对每个业务 view 设置骨架动画 // self.deviceOverView.tabAnimated = [[TABViewAnimated alloc] init]; self.networkActivityView.tabAnimated = [[TABViewAnimated alloc] init]; self.WifiActivityHeadView.tabAnimated = [[TABViewAnimated alloc] init]; self.wifiActivityChartView.tabAnimated = [[TABViewAnimated alloc] init]; self.apDensityContainerView.tabAnimated = [[TABViewAnimated alloc] init]; // // 对无法识别的业务view和错误使用空白占位view辅助识别 // SDNV6SiteDashboardDensitySkeletonView *skeletonView = [[SDNV6SiteDashboardDensitySkeletonView alloc] init]; // // // 添加到wifiView // [self.wifiActivityChartView addSubview:skeletonView]; // // 设置约束覆盖整个容器 // [skeletonView mas_makeConstraints:^(MASConstraintMaker *make) { // make.edges.equalTo(self.wifiActivityChartView); // }]; // 启动骨架动画 // [self.wifiActivityChartView layoutIfNeeded]; // skeletonView.tabAnimated = [[TABViewAnimated alloc] init]; // 调整骨架屏view // deviceView调整:只要启动回调,整个页面逻辑都会被破坏,TABA库的应用还是需要整体调整 // 先从整个dashboard页面出发,找出出现问题的原因,实在不行再尝试手动方案2 // 使用方案二 SDNSiteDashboardDeviceOverViewSkeletonView *deviceSkeletonView = [[SDNSiteDashboardDeviceOverViewSkeletonView alloc] init]; // 添加骨架 [_deviceOverView addSubview:deviceSkeletonView]; // 绑定约束 [deviceSkeletonView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(_deviceOverView); }]; // 启动骨架动画 [self.deviceOverView layoutIfNeeded]; deviceSkeletonView.tabAnimated = [[TABViewAnimated alloc] init]; // 添加骨架波浪动画效果 deviceSkeletonView.tabAnimated.superAnimationType = TABViewSuperAnimationTypeShimmer; // networkView调整 _networkActivityView.tabAnimated.superAnimationType = TABViewSuperAnimationTypeShimmer; _networkActivityView.tabAnimated.adjustBlock = ^(TABComponentManager * _Nonnull manager) { // 整体移除不需要和显示不清晰的标签 manager.animations(21, 3).remove(); // 底部两个重叠的骨架块 // 对顶部0-15部分的修改:标签栏部分与坐标 manager.animation(0).reducedWidth(-20).reducedHeight(-8).radius(4); // 与安卓对齐 manager.animation(1).remove(); manager.animation(3).remove(); manager.animation(4).remove(); manager.animation(6).remove(); manager.animation(7).remove(); manager.animation(10).remove(); manager.animation(11).remove(); manager.animation(13).remove(); manager.animation(14).remove(); // // 对2、5、8、9、12、15作为目前的主题进行修改 // 左侧标识修改 manager.animation(2).reducedWidth(-60).reducedHeight(-5).radius(4); manager.animation(9).reducedWidth(-60).reducedHeight(-5).radius(4); // 右侧标识修改 manager.animation(5).x_offset(-60).reducedWidth(-40).reducedHeight(-5).radius(4); manager.animation(8).x_offset(-20).reducedWidth(-40).reducedHeight(-5).radius(4); manager.animation(12).x_offset(-60).reducedWidth(-40).reducedHeight(-5).radius(4); manager.animation(15).x_offset(-20).reducedWidth(-40).reducedHeight(-5).radius(4); // 对底部16-24的修改 manager.animation(20).remove(); manager.animations(17, 2).remove(); manager.animation(16).radius(4); manager.animation(19).remove(); // manager.animation(19).x_offset(100).reducedWidth(40).reducedHeight(25).radius(4); }; // wifiheadView调整 _WifiActivityHeadView.tabAnimated.superAnimationType = TABViewSuperAnimationTypeShimmer; // wifiView调整:调整wifiView的骨架屏以遮蔽“WiFi Aciivity”标签尝试-失败 _wifiActivityChartView.tabAnimated.superAnimationType = TABViewSuperAnimationTypeShimmer; _wifiActivityChartView.tabAnimated.adjustBlock = ^(TABComponentManager * _Nonnull manager) { CGRect screenBounds = [UIScreen mainScreen].bounds; CGFloat screenWidth = CGRectGetWidth(screenBounds); // 移除不需要与显示不清晰的骨架组件 // manager.animation(1).remove(); manager.animation(2).remove(); manager.animation(3).remove(); // 3和4是底边骨架识别来源,但识别位置过远 manager.animation(4).remove(); // 调整2 iconView的位置 manager.animation(1).radius(4); // 创建标识6和7:对应Upload manager.create(6).leftEqualTo_offset(1, screenWidth/2 + 70).y(6).width(50).height(16).radius(4); manager.create(7).leftEqualTo_offset(1, screenWidth/2 + 40).y(6).width(20).height(16).radius(4); // 创建标识8和9:对应Download manager.create(8).leftEqualTo_offset(1, screenWidth/2 - 30).y(6).width(50).height(16).radius(4); manager.create(9).leftEqualTo_offset(1, screenWidth/2 - 60).y(6).width(20).height(16).radius(4); }; // ApView调整:创建ApView的骨架 _apDensityContainerView.tabAnimated.superAnimationType = TABViewSuperAnimationTypeShimmer; _apDensityContainerView.tabAnimated.adjustBlock = ^(TABComponentManager * _Nonnull manager) { CGRect screenBounds = [UIScreen mainScreen].bounds; CGFloat screenWidth = CGRectGetWidth(screenBounds); // 标识0:titleBlockView manager.create(0) .width(120) .height(20) .x(16) .y(16) .radius(4); // // 标识1:indicatorBlockView // manager.create(1) // .width(24) // .height(20) // .x(screenWidth - 16 - 32 - 24) // 右边缘减去边距和宽度 // .topEqualTo_offset(0, 0) // 与 titleBlockView 顶部对齐 // .radius(4); // 标识2:densityBlockView manager.create(2) .width(screenWidth - 32 - 32 - 8) .height(60) // 可根据实际内容高度调整 .x(16) .topEqualTo_offset(0, 36) // titleBlockView 底部 + 间距16 .radius(4); }; // 启动骨架动画(逐个) // [self.deviceOverView tab_startAnimation]; [self.networkActivityView tab_startAnimation]; [self.WifiActivityHeadView tab_startAnimation]; [self.wifiActivityChartView tab_startAnimation]; [self.apDensityContainerView tab_startAnimation]; // 启动替代骨架 [deviceSkeletonView tab_startAnimation]; // // 延迟 10 秒后结束骨架动画并加载 tableView // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //// [self.deviceOverView tab_endAnimation]; // [self.networkActivityView tab_endAnimation]; // [self.WifiActivityHeadView tab_endAnimation]; // [self.wifiActivityChartView tab_endAnimation]; // [self.apDensityContainerView tab_endAnimation]; // // // // 关闭并移除替代骨架 // [deviceSkeletonView tab_endAnimation]; // [deviceSkeletonView removeFromSuperview]; // }); // 第 0 秒:关闭并移除骨架容器 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [deviceSkeletonView tab_endAnimation]; [deviceSkeletonView removeFromSuperview]; }); // 第 2 秒:networkActivityView dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.networkActivityView tab_endAnimation]; }); // 第 4 秒:WifiActivityHeadView dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.WifiActivityHeadView tab_endAnimation]; }); // 第 6 秒:wifiActivityChartView dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.wifiActivityChartView tab_endAnimation]; }); // 第 8 秒:apDensityContainerView dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.apDensityContainerView tab_endAnimation]; }); } 参考的TABAnimated用法: // 自动生成+手动调整 self.networkActivityView.tabAnimated = [[TABViewAnimated alloc] init]; // networkView调整 _networkActivityView.tabAnimated.superAnimationType = TABViewSuperAnimationTypeShimmer; _networkActivityView.tabAnimated.adjustBlock = ^(TABComponentManager * _Nonnull manager) { // 整体移除不需要和显示不清晰的标签 manager.animations(21, 3).remove(); // 底部两个重叠的骨架块 // 对顶部0-15部分的修改:标签栏部分与坐标 manager.animation(0).reducedWidth(-20).reducedHeight(-8).radius(4); // 与安卓对齐 manager.animation(1).remove(); manager.animation(3).remove(); manager.animation(4).remove(); manager.animation(6).remove(); manager.animation(7).remove(); manager.animation(10).remove(); manager.animation(11).remove(); manager.animation(13).remove(); manager.animation(14).remove(); // // 对2、5、8、9、12、15作为目前的主题进行修改 // 左侧标识修改 manager.animation(2).reducedWidth(-60).reducedHeight(-5).radius(4); manager.animation(9).reducedWidth(-60).reducedHeight(-5).radius(4); // 右侧标识修改 manager.animation(5).x_offset(-60).reducedWidth(-40).reducedHeight(-5).radius(4); manager.animation(8).x_offset(-20).reducedWidth(-40).reducedHeight(-5).radius(4); manager.animation(12).x_offset(-60).reducedWidth(-40).reducedHeight(-5).radius(4); manager.animation(15).x_offset(-20).reducedWidth(-40).reducedHeight(-5).radius(4); // 对底部16-24的修改 manager.animation(20).remove(); manager.animations(17, 2).remove(); manager.animation(16).radius(4); manager.animation(19).remove(); // manager.animation(19).x_offset(100).reducedWidth(40).reducedHeight(25).radius(4); }; // 启动骨架屏 [self.networkActivityView tab_startAnimation]; // 关闭骨架屏 [self.networkActivityView tab_endAnimation]; 使用替代骨架屏视图,需要自己传递一个遮挡原有视图的骨架屏 替代骨架屏方案的TABAnimated库骨架屏实现 // 调整骨架屏view // deviceView调整:只要启动回调,整个页面逻辑都会被破坏,TABA库的应用还是需要整体调整 // 先从整个dashboard页面出发,找出出现问题的原因,实在不行再尝试手动方案2 // 使用方案二 SDNSiteDashboardDeviceOverViewSkeletonView *deviceSkeletonView = [[SDNSiteDashboardDeviceOverViewSkeletonView alloc] init]; // 添加骨架 [_deviceOverView addSubview:deviceSkeletonView]; // 绑定约束 [deviceSkeletonView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(_deviceOverView); }]; // 启动骨架动画 [self.deviceOverView layoutIfNeeded]; deviceSkeletonView.tabAnimated = [[TABViewAnimated alloc] init]; // 添加骨架波浪动画效果 deviceSkeletonView.tabAnimated.superAnimationType = TABViewSuperAnimationTypeShimmer; // 启动替代骨架 [deviceSkeletonView tab_startAnimation]; // 关闭替代骨架屏[deviceSkeletonView tab_endAnimation]; [deviceSkeletonView removeFromSuperview]; UITableView:TableView的TABAnimated库骨架屏实现 // 在慢加载中初始化 - (UITableView *)tableView { if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) style:UITableViewStyleGrouped]; _tableView.dataSource = self; _tableView.delegate = self; _tableView.estimatedRowHeight = 0; _tableView.estimatedSectionFooterHeight = 0; _tableView.estimatedSectionHeaderHeight = 0; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.backgroundColor = [UIColor tab_normalDynamicBackgroundColor]; // 设置tabAnimated相关属性 // 部分section有动画 _tableView.tabAnimated = [TABTableAnimated animatedWithCellClass:[TestTableViewCell class] cellHeight:100 animatedCount:1 toSection:1]; [_tableView.tabAnimated addHeaderViewClass:[LineTableViewHeaderFooterView class] viewHeight:60 toSection:1]; _tableView.tabAnimated.adjustWithClassBlock = ^(TABComponentManager *manager, __unsafe_unretained Class targetClass) { if (targetClass == TestTableViewCell.class) { manager.animation(1).down(3).height(12); manager.animation(2).height(12).width(110); manager.animation(3).down(-5).height(12); }else if (targetClass == LineTableViewHeaderFooterView.class) { manager.animation(2).right(3).height(14).down(16).reducedWidth(30).radius(2); } }; } return _tableView; } // 在UI初始化中启动骨架屏 /** initize view 视图初始化 */ - (void)initUI { [self.view addSubview:self.tableView]; [self.tableView tab_startAnimation]; // 开启动画 } // 获取到数据后进行对应骨架屏取消 /** 获取到数据后 */ - (void)afterGetData { [dataArray removeAllObjects]; // 模拟数据 for (int i = 0; i < 10; i ++) { Game *game = [[Game alloc]init]; game.gameId = [NSString stringWithFormat:@"%d",i]; game.title = [NSString stringWithFormat:@"这里是测试数据%d",i+1]; game.cover = @"test.jpg"; [dataArray addObject:game]; } // 停止动画,并刷新数据 [self.tableView tab_endAnimationWithIndex:1]; } UICollectionView的TABAnimated库骨架屏实现 // 1、初始化_collectionView.tabAnimated = [TABCollectionAnimated animatedWithCellClass:[NewsCollectionViewCell class] cellSize:[NewsCollectionViewCell cellSize]]; // 2、控制骨架屏开关 // 开启动画 [self.collectionView tab_startAnimation]; // 关闭动画 [self.collectionView tab_endAnimation]; // 3、预处理回调+链式语法用于修改骨架元素的属性 // 用变量名 _tableView.tabAnimated.adjustBlock = ^(TABComponentManager * _Nonnull manager) { manager.animationN(@"titleImageView").down(3).radius(12); manager.animationN(@"nameLabel").height(12).width(110); manager.animationN(@"timeButton").down(-5).height(12); }; // 用index修改 _tableView.tabAnimated.adjustBlock = ^(TABComponentManager * _Nonnull manager) { manager.animation(1).down(3).radius(12); manager.animation(2).height(12).width(110); manager.animation(3).down(-5).height(12); }; // 使用swift tableView.tabAnimated?.adjustBlock = { manager in manager.animation()?(1)?.down()(3)?.radius()(12) manager.animation()?(2)?.height()(12)?.width()(110) manager.animation()?(3)?.down()(-5)?.height()(12) }
最新发布
11-01
<think>嗯,用户问的是如何将Objective-C中的[(AppDelegate *)UIApplication.sharedApplication.delegate setup]这段代码转换成Swift。首先,我需要回忆一下两者的语法差异。 首先,Objective-C的UIApplication.sharedApplication在Swift中应该是UIApplication.shared,不过Swift 3之后可能更倾向于使用shared的属性方式。然后,delegate属性的获取,应该直接访问UIApplication.shared.delegate。不过需要注意到在Swift中,delegate返回的是UIApplicationDelegate?类型,所以需要进行强制解包或者可选链处理。 原来的代码是将delegate转换为AppDelegate类型,并调用setup方法。在Swift中,类型转换使用as!或者as?。这里如果用户确定delegate一定是AppDelegate实例,可以用强制转换as!。所以可能写成(UIApplication.shared.delegate as! AppDelegate).setup()。 不过,强制解包有风险,如果delegate不是AppDelegate的话会崩溃。或许更好的做法是用可选绑定,比如用if let或者guard let来处理。不过用户可能只是想直接转换,所以先给出基本方法,再提醒安全性问题。 另外,Swift中调用方法时不需要中括号,直接用点语法。所以整个结构应该是先获取shared实例,然后delegate,转换类型,再调用setup方法。 还需要检查是否有新的Swift语法变化,比如在最新的Swift版本中,UIApplication.shared是否是正确的方式。确认没问题后,给出正确的转换代码,并解释每一步的变化。同时,可能需要建议使用场景和注意事项,比如强制解包的风险,以及可选绑定的替代方案。</think>将Objective-C代码 `[(AppDelegate *)UIApplication.sharedApplication.delegate setup]` 转换为Swift的步骤如下: --- ### 一、逐层语法转换 1. **UIApplication.sharedApplication** → **UIApplication.shared** Swift中访问单例对象直接使用`.shared`属性。 2. **强制类型转换** → **as!** Objective-C的 `(AppDelegate *)` 在Swift中需使用强制类型转换操作符 `as!`(需确保类型安全)。 3. **方法调用语法** → **.setup()** Swift使用点语法调用方法,无需方括号。 --- ### 二、最终代码 ```swift (UIApplication.shared.delegate as! AppDelegate).setup() ``` --- ### 三、安全建议 (重要!⚠️) 1. **避免强制解包** 如果存在`delegate`可能不是`AppDelegate`类型的情况(如某些扩展场景),使用可选绑定更安全: ```swift if let appDelegate = UIApplication.shared.delegate as? AppDelegate { appDelegate.setup() } ``` 2. **架构优化建议** 直接通过`AppDelegate`单例访问更简洁: ```swift // 在AppDelegate中添加单例访问器 class AppDelegate: UIResponder, UIApplicationDelegate { static let shared = UIApplication.shared.delegate as! AppDelegate func setup() { ... } } // 调用方式 AppDelegate.shared.setup() ``` --- ### 四、代码差异对比表 | Objective-C | Swift | |--------------------------------------|--------------------------------------| | `UIApplication.sharedApplication` | `UIApplication.shared` | | `(AppDelegate *)` | `as! AppDelegate` | | `[obj method]` | `obj.method()` | --- ### 五、常见问题 **Q:为何使用`as!`而不是`as?`?** A:`as!`是强制转换,假设`delegate`一定是`AppDelegate`类型。如果存在不确定性,应使用`if let`配合`as?`实现安全解包。 **Q:Swift中能否省略类型转换?** A:不能。Swift是强类型语言,必须显式声明`delegate`的具体类型才能调用`AppDelegate`特有的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值