ios程序入口main及UIApplicationMain的研究

本文详细解析了iOS程序入口main函数及UIApplicationMain函数的工作原理,包括参数含义、事件循环的建立及用户事件处理流程。

接触ios也快有一年的时间了,把自己所学的所用的东西记录一下,从今天开始发博文,希望自己能坚持下去,把自己所学所懂纪录下来,方便自己以后查阅,也希望能帮到别人,特别是一些初学者。 

   废话少说,切入正题,学习一个新框架,在新框架下开发,需要了解一些框架知识,我们今天从程序的入口开始吧。

   先说main函数:

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

main函数有两个参数,argc是命令行总的参数个数,argv[]argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数,可能这么说大家不太明白是什么意思。作为c、c++、oc程序员经常看到main函数,但这两个参数很少会用,我觉得有部分程序员还是不太懂这两个参数,那么今天我们就打开xcode建立一个命令行工程来说明一下这两个参数。

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        // 先输出argc,看看是多少
        NSLog(@"argc = %d\n",argc);
        
        //然后再输出argv[]看看是什么
        for (int i = 0; i<argc; i++) {
            NSLog(@"%@\n",[NSString stringWithUTF8String:argv[i]]);
        }
    
    }
    return 0;
}


 建工程时我选择type 为  Foundation,没有选择c,在这里尽量用OC来讲解,执行程序后后输出:

 comandLineMain[1137:303] argc = 1

 comandLineMain[1137:303]/Users/mirinda/Library/Developer/Xcode/DerivedData/comandLineMaindgxwhsnwzgtljaehikedzrhgfzhy/Build/Products/Debug/comandLineMain

说明main函数默认情况下是带一个参数的,就是程序执行文件的全名。好现在为了更好的理解这两个参数,我们打开终端输入/Users/mirinda/Library/Developer/Xcode/DerivedData/comandLineMain-dgxwhsnwzgtljaehikedzrhgfzhy/Build/Products/Debug/comandLineMain ios step by step

看下面执行结果的截图:


  现在 argc = 5 因为我在执行文件全名后面添加了4个参数ios step by step

现在,大家应该很明白这几个参数了意思了吧。

现在我们继续研究下一个函数:

UIApplicationMain(argc, argv,nil,NSStringFromClass([AppDelegateclass])),研究这个函数我们需要看看函数原型,

int UIApplicationMain ( 
    int argc, 
    char *argv[], 
    NSString *principalClassName, 
    NSString *delegateClassName 
);

第一个和第二个函数是main函数的参数直接传进来的,第三参数

NSString *principalClassName,是应用程序类的名称,它必须是

UIApplication类或者其子类,

delegateClassName是应用程序类的代理类。如果pricipalClassNamenil,UIKit会用UIApplication类作为默认值,如果delegateClassNamenil,那么在nib/xib(在info.plist文件中指定,keyNSMainNibFile,使用Storyboards后则key为MainStoryboard文件中你就必须提供一个delegate对象给这个参数。此函数会根据principalClassName创建UIApplication对象,然后根据delegateClassName创建一个delegate对象,并将UIApplication对象中的delegate属性设置为delegate对象。接着会建立应用的main runloop。说到这里我要纠正一些网上博文一些不正确的地方,有些博文说:“

我的理解是第三个参数是应用本身的类,只是定义的类,确确实实的类,但它不干活,儿第四个参数delegateClassName,这个delegate类才是真正干活的,也是我们真正需要关心的东西

”,这样认为的同学其实没有深入研究,没有认真读官方文档,完全冤枉了UIApplication,最简单的方法进入UIApplication.h看看里面定义了很多方法,如果不干活定义那么多方法做什么?我们还是看一下官方文档,先看UIAppliationMain函数:This function is called in the main entry point to create the application object and the application delegate and set up the event cycle.看最后面的部分,set up the event cycle,建立了事件循环,只是建立事件循环,事件的处理分发并不是由它做的,是谁做的呢?正是被冤枉UIApplication对象。我们看UIApplication类的官方文档:A major role of a UIApplication object is to handle the initial routing of incoming user events. It also dispatches action messages forwarded to it by control objects (UIControl) to the appropriate target objects. In addition, the UIApplication object maintains a list of all the windows (UIWindow objects) currently open in the application, so through those it can retrieve any of the application’s UIView objects. The application object is typically assigned a delegate, an object that the application informs of significant runtime events—for example, application launch, low-memory warnings, and application termination—giving it an opportunity to respond appropriately.也就是说:

UIApplication的一个主要工作是处理用户事件,它会起一个队列,把所有用户事件都放入队列,逐个处理,在处理的时候,它会发送当前事件到一个合适的处理事件的目标控件。此外,UIApplication实例还维护一个在本应用中打开的window列表(UIWindow实例),这样它就可以接触应用中的任何一个UIView对象。UIApplication实例会被赋予一个代理对象,以处理应用程序的生命周期事件(比如程序启动和关闭)、系统事件(比如来电、记事项警告)等等。正是因为它维护了一个windows列表,所以他才知道消息该发往哪里。 为了大家更好的理解,我举个简单的例子,其实ios的消息循环 就如我们的邮政系统,UIAppliationMain函数了就是建立这个邮政系统的机构 ,也就相当于我们的政府,UIApplication就是邮局,用户对手机的各种输入,就相当于人们寄送了一些信件,邮局就会根据地址把信送到收件人手里,而UIApplicationDelegate就是其中的一部分收件人。而收件人收到信后会做何种处理呢?收件人一看是寄给自己的,可能就打开看了,可能看了信后做了某些事情,就相当于程序里某个对象接到消息后做了某些处理;还有可能就是收件人收到信后一看,不是给自己的,是转给某人A的,这时候收件人就把信件交给了A,然后A看完信后做了后做了某些事情。这就是我们所说的事件响应链(responder类及其子类相关),这里不多说,以后会有介绍。还有种情况,就是人物A到信后,一看是C寄来的,这封信有可能是寄给A的,也有可能是要求A转给B的,但是A非常讨厌C,就把信扔到一边不再理会,这就造成了事件响应链的断裂。

看完这些应该对ios程序入口main及UIApplicationMain有所了解了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值