面试题(一)

2019-09-13 22:56栏目:编程学习

xcode5之后新创制的工程默许都是ARC的,那就招致在didFinishLaunch中开创的window未有人负有,进而在脱离该函数时,那个window都会被放出掉,所以显得不出来。应用方案:1、将工程改成非ARC2、要制造的window改称类的属性,防止出了函数时新创立的window被假释

1.主次的启航流程

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

能够看出main函数会调用UIApplicationMain函数,它的八个参数的情致是:
argc: 代表前后相继在步入main函数时的参数的个数。默感觉1。
argv: 代表包括的依次参数。默感觉程序的名字。
principalClassName: UIApplication要么它的子类的名字, 假若传入的是nil, 则表示UIApplication的名字, 即@"UIApplication"。
delegateClassName: UIApplication的代理的名字。
UIApplicationMain函数中,依据传入的UIApplication名称和它的代办的称呼,会器重做上面包车型大巴业务:

  • 依附传入的名目创设UIApplication对象。
  • 据书上说传入的代理名称创设UIApplication代理对象。
  • 张开事件循环(假若不举办巡回,那么在main函数截止后前后相继就得了了。要力保程序创建后可以直接存在)。
  • 解析Info.plist文件:
  • 会在Info.plist文件里索求Main storyboard file base name那几个Key对应的Value是不是有值。借使有值,则象征将来会通过Storyboard加载调节器,AppDelegate会接收到didFinishLaunchingWithOptions音信(程序运转成功的时候),此时Storyboard会举行一密密麻麻的加载操作(前面会具体说);如果未有值,则不会通过Storyboard加载调整器,接着AppDelegate会接收到didFinishLaunchingWithOptions音信(程序运转成功的时候),在今年要求大家透过代码的艺术加载调控器。
    留心Info.plist中Main storyboard file base name这么些Key并非当真的Key,而是苹果为了加强可读性才这么写的,真正的Key为UIMainStoryboardFile(能够透过Info.plist文件的源代码查看)。
    那就是在想要用代码格局开创调控器并不是Storyboard成立调整器的时候怎么先要将Main Interface设置为空白,这样在剖判Info.plist文件的时候才会知道不通过Storyboard成立调控器。
    透过能够精通,分析Info.plist文件这一操作首假诺看我们用的是Storyboard格局加载如故代码的艺术加载。默许Main storyboard file base name为Main,也正是经过Storyboard格局加载调控器。
    今日具体分析一下,通过Storyboard方式加载调节器和代码格局加载调节器。

通过Storyboard

透过Storyboard,紧要做了上面包车型地铁事体(这几个事情无需大家做,是系统活动完结的,在程序运转完结的时候):
创办窗口。
创制贰个UIWindow的实例用来展现分界面。
安装窗口的根调整器。
根据Storyboard的装置,创立一个调整器。
再便是安装那个调控器为事先成立的window的根调控器。
来得窗口。(也正是前面提到的makeKeyAndVisible
设置self.window可知何况设置UIApplication的keyWindow。
在这一步上将根调控器的view增加到window上。
如果main interface中写了Main,那么就直接加载Main.storyboard,再加载箭头指向的调节器,以及中间的views 和子控件,当加载完结,编写翻译器会自行调用 -viewdidload 方法,表明控件都加载落成

经过代码格局

因此代码的法子,供给我们在didFinishLaunchingWithOptions主意中打开加载调控器的相干操作。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIViewController *viewController = [[UIViewController alloc] init];
    self.window.rootViewController = viewController;
    // 此时根控制器的view还没有加到self.window上
    [self.window makeKeyAndVisible];
    // 此时根控制器的view加到self.window上
    return YES;
}
补充

window是有层级的,何况能够有八个window同期设有。比如:状态栏便是一个window,键盘也是一个window。
能够透过设置UIWindow的指标的windowLevel属性来调解层级。
self.window.windowLevel = UIWindowLevelStatusBar;
window共有几种等第:UIWindowLevelNormal,UIWindowLevelStatusBar UIWindowLevelAlert。假诺二种等第同有时候出现在荧屏上,那么alert在最上面,statusBar在中游,normal则在最上面。
留意:假使二个前后相继中有四个window,调控器默许会把状态栏掩盖。
解决办法:关闭调节器对状态栏的操纵,(为Info.plist增加View controller-based status bar appearance这个key并设置为NO)如此这般这个window以及气象栏就能够按层级关系平常化呈现。

总结

1.先奉行main函数,main内部会调用UIApplicationMain函数
2.UIApplicationMain函数里面做了怎么样业务:
(1)创建UIApplication对象
(2)创建UIApplication的delegate对象—–PYAppDelegate
(3)开启三个新闻循环:每监听到相应的系统事件时,就能打招呼MJAppDelegate
(4)为应用程序成立八个UIWindow对象(承继自UIView),设置为PYAppDelegate的window属性
(5)加载Info.plist文件,读取最要紧storyboard文件的称呼
(6)加载最尊崇的storyboard文件,成立金黄箭头所指的调控器对象
(7)何况安装第6步创造的调控器为UIWindow的rootViewController属性(根调控器)
(8)呈现UIWindow,体现以前会将增添rootViewController的view到UIWindow上边(在这一步才会成立调控器的view)

2.单例情势

  • 怎么是单例
    单例格局是一种常用的软件设计方式。在它的着力结构中只含有叁个被誉为单例类的特殊类。通过单例情势能够有限协理系统中三个类唯有两个实例并且该实例易于外部访谈,进而方便对实例个数的操纵并节约系统能源。若是希望在系统中有个别类的对象只可以存在一个,单例格局是最佳的消除方案。
  • 创建单例的方法
#import "SingleInstance.h"
@interface SingleInstance ()<NSCopying,NSMutableCopying>

@end

//定义一个当前单例对象的一个实例,并赋值为nil
static SingleInstance *instance = nil;

@implementation SingleInstance

//单例创建一:
  (instancetype)sharedInstance
{
    @synchronized(self)
    {
        if (!instance)
        {
            //不存在就创建当前单例对象
            instance = [[self alloc] init];
        }
        return instance;
    }
}

//单例创建二:
  (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

//alloc会触发,防止通过alloc创建一个不同的实例
  (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
}

- (id)copyWithZone:(nullable NSZone *)zone
{
    return self;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone
{
    return self;
}

//手动内存管理下写这些

- (instancetype)retain
{
    return self;
}

- (oneway void)release
{

}

- (instancetype)autorelease
{
    return self;
}

- (NSUInteger)retainCount
{
    return MAXFLOAT;
}

- (void)dealloc
{

}
@end

注意

只写 (instancetype)sharedInstance是提供了三个实例的大局访谈点,并不是当真的单例。真正的单例供给重载全部和创办有关的章程,倘诺是非 ARC,还要重载 release、retain 等措施,要求那些办法相当多,不过你能够写贰个宏来重载全数这几个点子,一键实现单例.

  • 运用情形
    打个大约的只要,比方您上了五个必要登记的网址,然后你点一投注册按键就能够跳出来二个亟需填写消息的页面,倘令你未有对那个页面使用单例形式你再点一下登记,就能又跳出二个长期以来的页面,使用单例格局之后,效能正是在未曾把上多少个填写音讯的页面关闭在此以前是不会再跳出多个均等的页面的,所以你在程序设计的时候要想了然什么是不得不被实例化一次的指标,然后利用单例形式完毕。(音乐播放器,windows的财富管理器)
  • 优缺点
    优点
    1、减弱内部存款和储蓄器费用和连串性格费用;
    2、制止对资源的数不完占用;
    3、优化和分享能源访谈。
    4.实例调节:Singleton 会阻止其余对象实例化其和煦的 Singleton 对象的别本,进而确认保证全数指标都访谈独一实例。
    5.灵活性:因为类调整了实例化进程,所以类能够越来越灵活修改实例化进程
    缺点
    1、单例格局尚未接口,扩张很不便;
    2、单例方式与纯粹任务有龃龉。

ARC下dealloc存在的含义

MRC下dealloc 方法

实际上在MRC中dealloc方法存在的基本点意义是为了
放飞本身的实例变量,
移除观望者,
停止timer,
移除告示,
代办置空等。
静心MRC 下dealoc 方法肯定要在终极写
[super dealloc];
ARC下 系统会帮助我们释放该对象所包涵的实例变量,不过多少对象仍旧供给们融洽去自由的(譬喻Core Foundation框架下的一对对象),其他布告中观看者的移除,代理置空,结束timer等
演示如下所示:
早晚无法有 [super dealloc];

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];//移除通知观察者
    [[DataManager sharedManager] removeFromDelegateQueue:self];//移除委托引用
    [[MyClass shareInstance]  doSomething ]//其他操作
    scrollView.delegate = nil;
    [timer invalidate];  
}

版权声明:本文由威尼斯人app发布于编程学习,转载请注明出处:面试题(一)