皮皮网
皮皮网

【stage源码拆分】【智行源码】【源码的修改】ios 11 源码

来源:安卓手机源码 发表时间:2024-11-27 05:35:08

1.苹果11.26可不可以越狱啊
2.xcode调试心得
3.求一个小型学生理财系统的面向对象程序设计的源代码
4.一键自动修改和翻新OC源码,解决苹果审核4.3和马甲问题
5.苹果11怎么设置apn接入点?
6.30分钟学会iOS 11开发环境xcode 9图文教程

ios 11 源码

苹果11.26可不可以越狱啊

       近日iOS 越狱开发者CoolStar透露,已经拿到最新公开的 iOS .2~.2.6核心漏洞,这也预示着不久后 Electra 越狱工具更新,就可在 iOS 更高版本上支持越狱,建议停留在 iOS .2 ~ .2.6 用户,stage源码拆分请维持好当前 iOS 版本,等待越狱放出。

       之前在 iOS .3 上被修复的核心漏洞 CVE-- 已经被公开,在苹果安全修复说明页面上指出,这是由一位匿名者发现的核心漏洞,该漏洞能够改变内存处理器机制,造成多个内存损坏,只要通过破解程式借由此漏洞就可获得核心权限,并且执行任意代码,对越狱工具来说算是一个相当大的突破。

       而这位匿名者在近日已经将 CVE-- 漏洞源代码分享给 CoolStar,用来开发越狱工具,智行源码希望他能够解决目前开发 iOS .3 所面临的困境,看起来 CoolStar 似乎正准备朝 iOS .3 迈进,不过目前遇到了一些阻碍。

       而CoolStar 在收到核心漏洞后,留下了一句话: iOS .2~.2.6 请保持当前的固件版本,这似乎就可以证实 @cmwdotme 所提供的 CVE-- 核心漏洞,确实可以让越狱工具更迈进一步,也预示了不久后推出 iOS .2 - iOS .2.6 越狱工具的可能性非常大。

       对于普通用户来说,这确实是一个振奋人心的消息,有鉴于CoolStar已经推出了iOS.0-.1.2越狱,所以这次CoolStar的说法可信度是非常高的,iOS .2~.2.6用户需要做的就是耐心等待。

xcode调试心得

       没有系统的学习和总结过Xcode调试相关的知识,这里参考/里面的教程,总结一下调试相关的知识,算半拉翻译,源码的修改半拉总结吧

崩溃的表现一般来说:

SIGABRT(好处理)

EXC_BAD_ACCESS(一般内存问题)

SIGBUS

SIGSEGV

       左面工具栏会按照线程分出bug所在,thread1一般主线程,其他线程的问题会在自己的位置显示。点开里面的方法都是看不懂的汇编(其实以前学过)。

       对于Xcode下方有提示的bug一般很好解决,但是有时候只是简单的EXC_BAD_ACCESS,无从下手,左面工具栏中的方法也看不出所以然,这时要把顶部工具栏的breakpoint打开,也许左面就会显示出更多出问题的方法,如图打开brekpoints以后多出了所选的方法提示,找到了是数组的问题。当然也可以在左面下方滑块调节来显示出更多提示的方法。

       总结的来说,就是在左面栏里找到出问题的地方

App启动的流程

       上面的图的调用关系说明了App是怎么启动的,除了main方法,其他方法都是看不到的,默认封装到系统的抢购app源码framework里,没法看源码

方法引用错误一般来说:

       [UINavigationController setList:]: unrecognized selector sent to instance 0x6d4ed

1 [UINavigationController setList:]: unrecognized selector sent to instance 0x6d4ed

       这种要不就是这个类没这个方法,或者调用方法的对象错误,或者拼错,比较简单

看打印信息

       没有打印信息的时候,可以点这个,有时候需要多点几次,可以有更详细的错误打印信息,lldb调试输入c功能是一样的,都是让程序继续运行

This class is not key value coding-compliant

       Problems[:f] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is notkey value coding-compliant for the key button.'

1

        2

        3

        4

        5 Problems[:f] *** Terminating app due to uncaught exception 'NSUnknownKeyException',

       reason: '[ setValue:forUndefinedKey:]: this class is not

       key value coding-compliant for the key button.'

       1.有时会碰到这种错误,印象里是请求的网络列表返回为空,出现了个这么诡异的现象,这是一种情况。

       2.NSUnknownKeyException指示了未知的key,而这个未知的key出现在MainViewController里,这个key的名字是button

       先看nib,在这个例子里有一个button,和MainViewController的翻转坐标源码属性button连接了IBOutlet,但是@property对应的@synthesize没有写,出现了这个问题,虽然在iOS6可以不用写@synthesize了,但是在老版本可能还会出现这个问题

       3.总结一下,“This class is not key value coding-compliant”这个问题出现在NIB相关的地方,一般是iboutlet已经连接,但是这个属性却不存在,常常发生在ib连着呢,属性给删了。

使用DEBUGGER

       [self performSegueWithIdentifier:@"ModalSegue" sender:sender];

1 [self performSegueWithIdentifier:@"ModalSegue" sender:sender];

       这句话出问题了,不知道怎么处理,可以在左面选中抛出的异常expection_throw

       用LLDB的debugger po $eax会调用description方法,打印全部信息

       po是point object,$eax是当前cpu注册者之一,如果选中了异常错误输入这个命令,这个注册者就是NSException对象,注意$eax是用于模拟器的,真机要用$r0

       可以看大原因了,是segue问题,storyboard中的问题这里就定位了

       类似的,还有这些debugger方法

       po [$eax class] //可以看到 (id) $2 = 0xe NSException,数字不重要NSException是问题的名字po [$eax name]//得到exception的名字po[$eax reason]//得到错误原因(unsigned int) $4 = Receiver () has no segue with identifier 'ModalSegue'

1

        2

        3

        4

        5 po [$eax class] //可以看到 (id) $2 = 0xe NSException,数字不重要NSException是问题的名字

       po [$eax name]//得到exception的名字

       po[$eax reason]//得到错误原因(unsigned int) $4 = Receiver () has no segue with identifier 'ModalSegue'

NSAssert用法

       - (void)doSomethingWithAString:(NSString *)theString{ NSAssert(theString != nil, @"String cannot be nil");NSAssert([theString length] = 3, @"String is too short");. . .}

1

        2

        3

        4

        5

        6

        7

        8

        9

       

        - (void)doSomethingWithAString:(NSString *)theString

       {

       NSAssert(theString != nil, @"String cannot be nil");

       NSAssert([theString length] = 3, @"String is too short");

       . . .

       }

       NSAssert最为一种防御型的代码,目的就是一有错,程序就伴随着异常崩溃,或者说停止运行,不往下进行。上面的代码当传入空数组的时候就会打印这个:

       -- ::. Problems[:c] *** Assertion failure in -[MainViewController doSomethingWithAString:], /Users/lipengxuan/Downloads/Problems/Problems/MainViewController.m:

1 -- ::. Problems[:c] *** Assertion failure in -[MainViewController doSomethingWithAString:], /Users/lipengxuan/Downloads/Problems/Problems/MainViewController.m:

       有的时候程序崩溃打印信息就会出现Assertion,那么就是这句话起作用了,这个时候可以继续运行(lldb c),可以看到更详细的打印信息。

       总结一下,遇到Assertion failure,就可以下一步运行看更详细的信息

BreakPoint使用breakpoint 分Exception breakPoint和breakPoint

       Exception breakPoint:程序崩溃异常了会立刻暂停到断点,点加号第一个就是添加Exception断点

       breakPoint:随意放

       Finally!终于到了传说中的打断点,这个很基本很经典的调试方法,事实上,断点和NSLog用法差不多,只不过不用你去写了

       一个简单的例子,现在有个这么个方法

       - (id)initWithStyle:(UITableViewStyle)style{ NSLog(@"init with style");if (self == [super initWithStyle:style]){ list = [NSMutableArray arrayWithCapacity:];[list addObject:@"One"];[list addObject:@"Two"];[list addObject:@"Three"];[list addObject:@"Four"];[list addObject:@"Five"];}return self;}

1

        2

        3

        4

        5

        6

        7

        8

        9

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

        - (id)initWithStyle:(UITableViewStyle)style

       {

       NSLog(@"init with style");

       if (self == [super initWithStyle:style])

       {

       list = [NSMutableArray arrayWithCapacity:];

       [list addObject:@"One"];

       [list addObject:@"Two"];

       [list addObject:@"Three"];

       [list addObject:@"Four"];

       [list addObject:@"Five"];

       }

       return self;

       }

       程序运行后我发现貌似这个方法没有执行,这是一种猜测,通常我会在方法里加入打印信息,也可以打断点,在方法定义的地方加断点,如果调用这个方法了,就会停止在这里,起到了一样的作用。

       接着是单步调试

       打断点,然后点击跳跃的箭头,就可以一步步的执行了,更精细的步骤可以F6,期间可以随时打印想看的变量,比如在tableview的cellForRowAtIndexPath函数中用po indexPath打印出indexPath的值

       (NSIndexPath *) $3 = 0x 2 indexes [0, 1]

1 (NSIndexPath *) $3 = 0x 2 indexes [0, 1]

       意思就是section 0 row 1

       这样进行一步打印一次,可以看出indexes也在变化,知道出问题的敌方

       Problems[:f] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]'*** First throw call stack:(NSIndexPath *) $ = 0xa8a6c0 2 indexes [0, 5]

1

        2

        3

        4

        5

        6

        7 Problems[:f] *** Terminating app due to uncaught exception 'NSRangeException',

       reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]'

       *** First throw call stack:

       (NSIndexPath *) $ = 0xa8a6c0 2 indexes [0, 5]

       单步调试找出来了index row=5超出了数组的范围

       总结一下,po命令非常实用,只要找到正确的调用方法,就可以打印对象信息

ZOMBIES问题EXC_BAD_ACCESS问题一般是内存问题,比如下面这种情况

       程序停在了这里,EXC_BAD_ACCESS问题,但是也不知道具体问题是什么,这时候可以用zombie 工具检测

       Xcode点击左上角项目名字-Edit Scheme-Diagnostics-Enable Zombie Objects,OK再次运行

       会多出这段话

       -- ::. Problems[:c] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0xcbe

1 -- ::. Problems[:c] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0xcbe

       这段话什么意思呢?

       创建一个对象,alloc一个对象会分配给这个对象一块内存,党这个对象release了,引用计数归零了,这块内存就会dealloc掉,之后其他对象就可以用这块内存。

       但是可能有这样一种情况,正在有对象使用的内存被另一个对象企图指向使用,或者已经被释放的内存企图再次被释放。

       僵尸工具的作用是让对象被released的时候,内存不dealloc,这块内存被标记为“undead”,如果其他对象想再用这块内存,app可以识别出错误并显示“message sent to deallocated instance”,就像上面的那段话一样。结合上面的代码

       cell.textLabel.text = [list objectAtIndex:indexPath.row];

1 cell.textLabel.text = [list objectAtIndex:indexPath.row];

       这段话就是zombie对象出现的地方,一般来说textLabel 还有indexPath.row应该没问题,问题应该出现在list这个数组,而且zombie tool也说了是[__NSArrayM objectAtIndex:]的问题,利用NSLog打印list,可以看到内存地址和错误的地址相同,那么错误就定义在list了

       -- ::. Problems[:c] list is 0xb0ed-- ::. Problems[:c] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0xb0ed0

1

        2

        3 -- ::. Problems[:c] list is 0xb0ed0

       -- ::. Problems[:c] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0xb0ed0

       当然用dubugger 命令 p list也可以打印出这个结果

       这就是zombie 工具起的作用,解决内存问题

       总结的来说,如果出现了EXC_BAD_ACCESS错误,打开僵尸工具,再试一遍。但是没问题的时候不要打开这个工具,因为这个工具从不dealloc内存,只是标记内存为”undead”,会导致内存泄露,所以用的时候再打开,诊断后再关掉。

习惯问题应该看bug一样的视线看warning,能修复就修复。

       - (void)buttonTapped:(id)sender{ NSLog(@"You tapped on: %s", sender);}

1

        2

        3

        4

        5

        6

        7 - (void)buttonTapped:(id)sender

       {

       NSLog(@"You tapped on: %s", sender);

       }

       比如这个按钮点击事件,%s是打印C-String,就是末尾是NUL的字符串,但是这里sender是按钮对象,所以会崩溃,不能忽略警告

求一个小型学生理财系统的面向对象程序设计的源代码

       #include <iostream.h>

       #include <fstream.h>

       #include <string.h>

       #include <stdlib.h>

       const unsigned int COUNT = 5;//账户数量为5

       typedef struct Money{

        int Date;

        float money;

        Money *next;

       }Income,Expense;

       typedef struct{

        Income *income;//收入记录

        Expense *expense;//支出记录

        float incomeaccount;//收入统计

        float expenseaccount;//支出统计

        int incomelenght;

        int expenselenght;

       }Account;

       class AccountInformation{

       private:

        Account L[COUNT];

       public:

        AccountInformation();

        ~AccountInformation();

        int InitAccount();

        void getExpense(int choice[]);

        void getIncome(int choice[]);

        void addExpense(int choice,Expense *elem);

        void addIncome(int choice,Expense *elem);

        void updateIncome(int choice,Expense elem);

        void updateExpense(int choice,Expense elem);

        void deleteIncome(int choice,int date);

        void deleteExpense(int choice,int date);

        void countAll();

        void saveInfo();

       };

       AccountInformation::AccountInformation()

       {

        InitAccount();

       }

       AccountInformation::~AccountInformation()

       {

       }

       int AccountInformation::InitAccount()

       {

        for(int i=0;i<COUNT;i++)

        {

        L[i].income=new Income;

        L[i].expense=new Expense;

        if(L[i].income==NULL||L[i].expense==NULL)

        {

        cout<<"分配内存失败."<<endl;

        return 0;

        }

        L[i].incomelenght=0;

        L[i].expenselenght=0;

        L[i].incomeaccount=0;

        L[i].expenseaccount=0;

        }

        Money *Q,*P;

        char s[2];

        //读取收入信息

        ifstream fin1("income.txt");

        if(fin1.fail())

        {

        cout<<"文件打开失败!"<<endl;

        return 0;

        }

        for(i=0;i<COUNT;i++)

        {

        fin1>>s;

        Q=L[i].income;

        while(s[0]!='#')

        {

        if((int)s[1]==0)

        Q->Date=(int)s[0]-;

        else

        Q->Date=((int)s[0]-)*+(int)s[1]-;

        fin1>>Q->money;

        Q->next=new Income;

        L[i].incomelenght++;

        L[i].incomeaccount+=Q->money;

        P=Q;

        Q=Q->next;

        fin1>>s;

        }

        P->next=NULL;

        }

        fin1.close();

        //读取支出信息

        ifstream fin2("expense.txt");

        if(fin2.fail())

        {

        cout<<"文件打开失败!"<<endl;

        return 0;

        }

        for(i=0;i<COUNT;i++)

        {

        fin2>>s;

        Q=L[i].expense;

        while(s[0]!='#')

        {

        if((int)s[1]==0)

        Q->Date=(int)s[0]-;

        else

        Q->Date=((int)s[0]-)*+(int)s[1]-;

        fin2>>Q->money;

        Q->next=new Income;

        L[i].expenselenght++;

        L[i].expenseaccount+=Q->money;

        P=Q;

        Q=Q->next;

        fin2>>s;

        }

        P->next=NULL;

        }

        fin2.close();

        return 1;

       }

       void AccountInformation::getExpense(int choice[])

       {

        Expense *Q;

        float m=0.0;

        for(int i=0;i<COUNT;i++)

        if(choice[i]!=0)

        {

        Q=L[choice[i]-1].expense;

        cout<<"账户"<<choice[i]<<"的支出信息为"<<endl;

        cout<<"DATE\tMONEY"<<endl;

        while(Q!=NULL)

        {

        cout<<Q->Date<<"\t"<<Q->money<<endl;

        Q=Q->next;

        }

        cout<<"账户"<<choice[i]<<"的总支出信息为"<<L[choice[i]-1].expenseaccount<<endl<<endl;

        m+=L[choice[i]-1].expenseaccount;

        }

        cout<<"总支出信息为"<<m<<endl;

       }

       void AccountInformation::getIncome(int choice[])

       {

        Income *Q;

        float m=0.0;

        for(int i=0;i<COUNT;i++)

        if(choice[i]!=0)

        {

        Q=L[choice[i]-1].income;

        cout<<"账户"<<choice[i]<<"的收入信息为"<<endl;

        cout<<"DATE\tMONEY"<<endl;

        while(Q!=NULL)

        {

        cout<<Q->Date<<"\t"<<Q->money<<endl;

        Q=Q->next;

        }

        cout<<"账户"<<choice[i]<<"的总收入信息为"<<L[choice[i]-1].incomeaccount<<endl<<endl;

        m+=L[choice[i]-1].incomeaccount;

        }

        cout<<"总收入信息为"<<m<<endl;

       }

       void AccountInformation::addExpense(int choice,Expense *elem)

       {

        Expense *Q,*P;

        Q=L[choice-1].expense;

        while(Q!=NULL)

        {

        if(Q->Date==elem->Date)

        {

        Q->money+=elem->money;

        L[choice-1].expenseaccount+=elem->money;

        return ;

        }

        if(Q->Date>elem->Date&&P->Date<elem->Date)

        break;

        P=Q;

        Q=Q->next;

        }

        P->next=elem;

        elem->next=Q;

        L[choice-1].expenseaccount+=elem->money;

        L[choice-1].expenselenght++;

       }

       void AccountInformation::addIncome(int choice,Expense *elem)

       {

        Expense *Q,*P;

        Q=L[choice-1].income;

        while(Q!=NULL)

        {

        if(Q->Date==elem->Date)

        {

        Q->money+=elem->money;

        L[choice-1].incomeaccount+=elem->money;

        return ;

        }

        if(Q->Date>elem->Date&&P->Date<elem->Date)

        break;

        P=Q;

        Q=Q->next;

        }

        P->next=elem;

        elem->next=Q;

        L[choice-1].incomeaccount+=elem->money;

        L[choice-1].incomelenght++;

       }

       void AccountInformation::updateExpense(int choice,Expense elem)

       {

        Expense *Q;

        Q=L[choice-1].expense;

        while(Q!=NULL)

        {

        if(Q->Date==elem.Date)

        {

        Q->money=elem.money;

        L[choice-1].expenseaccount=elem.money-Q->money;

        return ;

        }

        Q=Q->next;

        }

       }

       void AccountInformation::updateIncome(int choice,Expense elem)

       {

        Expense *Q;

        Q=L[choice-1].income;

        while(Q!=NULL)

        {

        if(Q->Date==elem.Date)

        {

        Q->money=elem.money;

        L[choice-1].incomeaccount=elem.money-Q->money;

        return ;

        }

        Q=Q->next;

        }

       }

       void AccountInformation::deleteExpense(int choice,int date)

       {

        Expense *Q,*P;

        Q=L[choice-1].expense;

        if(Q->Date==date)

        {

        L[choice-1].expense=NULL;

        L[choice-1].expenseaccount=0.0;

        L[choice-1].expenselenght=0;

        }

        while(Q!=NULL)

        {

        if(Q->Date==date)

        {

        P->next=Q->next;

        L[choice-1].expenseaccount-=Q->money;

        L[choice-1].expenselenght--;

        return ;

        }

        P=Q;

        Q=Q->next;

        }

       }

       void AccountInformation::deleteIncome(int choice,int date)

       {

        Expense *Q,*P;

        Q=L[choice-1].income;

        if(Q->Date==date)

        {

        L[choice-1].income=NULL;

        L[choice-1].incomeaccount=0.0;

        L[choice-1].incomelenght=0;

        }

        while(Q!=NULL)

        {

        if(Q->Date==date)

        {

        P->next=Q->next;

        L[choice-1].incomeaccount-=Q->money;

        L[choice-1].incomelenght--;

        return ;

        }

        P=Q;

        Q=Q->next;

        }

       }

       void AccountInformation::countAll()

       {

        Expense *Q;

        float allincome=0.0;//总收入

        float allexpense=0.0;//总支出

        float a[COUNT],b[COUNT],c[COUNT],d[COUNT];

        int date1,date2;

        for(int i=0;i<COUNT;i++)

        {

        //收入信息

        Q=L[i].income;

        date1=Q->Date;

        date2=Q->Date;

        while (Q!=NULL)

        {

        if(Q->Date<date1)

        date1=Q->Date;

        if(Q->Date>date2)

        date2=Q->Date;

        Q=Q->next;

        }

        a[i]=L[i].incomeaccount/(date2-date1);//单位时间收入

        c[i]=L[i].incomeaccount;//账户总收入

        allincome+=L[i].incomeaccount;//总收入

        //支出信息

        Q=L[i].expense;

        date1=Q->Date;

        date2=Q->Date;

        while (Q!=NULL)

        {

        if(Q->Date<date1)

        date1=Q->Date;

        if(Q->Date>date2)

        date2=Q->Date;

        Q=Q->next;

        }

        b[i]=L[i].expenseaccount/(date2-date1);//单位时间支出

        d[i]=L[i].expenseaccount;//账户总支出

        allexpense+=L[i].expenseaccount;//总支出

        }

        int k[COUNT]={ 1,2,3,4,5};

        int l[COUNT]={ 1,2,3,4,5};

        int t;

        float f;

        for(i=0;i<COUNT-1;i++)

        for(int j=i+1;j<COUNT;j++)

        if(a[i]>a[j])

        {

        f=a[j];

        a[j]=a[i];

        a[i]=f;

        t=k[j];

        k[j]=k[i];

        k[i]=t;

        }

        else if(c[i]>c[j])

        {

        f=c[j];

        c[j]=c[i];

        c[i]=f;

        t=l[j];

        l[j]=l[i];

        l[i]=t;

        }

        cout<<"总收入为:"<<allincome<<endl;

        cout<<"账户收入分别为:\t\t单位时间内账户收入为:"<<endl;

        for(i=0;i<COUNT;i++)

        cout<<"账户"<<l[i]<<"的收入为:"<<c[i]<<"\t账户"<<k[i]<<"的收入为"<<a[i]<<endl;

        for(i=0;i<COUNT;i++)

        {

        k[i]=i+1;

        l[i]=i+1;

        }

        for(i=0;i<COUNT-1;i++)

        for(int j=i+1;j<COUNT;j++)

        if(b[i]>b[j])

        {

        f=a[j];

        a[j]=a[i];

        a[i]=f;

        t=k[j];

        k[j]=k[i];

        k[i]=t;

        }

        else if(d[i]>d[j])

        {

        f=c[j];

        c[j]=c[i];

        c[i]=f;

        t=l[j];

        l[j]=l[i];

        l[i]=t;

        }

        cout<<"总支出为:"<<allincome<<endl;

        cout<<"账户支出分别为:\t\t单位时间内账户支出为:"<<endl;

        for(i=0;i<COUNT;i++)

        cout<<"账户"<<l[i]<<"的支出为:"<<d[i]<<"\t账户"<<k[i]<<"的支出为"<<b[i]<<endl;

       }

       void AccountInformation::saveInfo()

       {

        Money *Q;

        ofstream fout1("income.txt",ios::trunc);

        if(fout1.fail())

        {

        cout<<"文件打开失败!"<<endl;

        return ;

        }

        for(int i=0;i<COUNT;i++)

        {

        Q=L[i].income;

        while(Q!=NULL)

        {

        fout1<<Q->Date<<" "<<Q->money<<'\n';

        Q=Q->next;

        }

        fout1<<"#\n";

        }

        fout1.close();

        ofstream fout2("expense.txt",ios::trunc);

        if(fout2.fail())

        {

        cout<<"文件打开失败!"<<endl;

        return ;

        }

        for(i=0;i<COUNT;i++)

        {

        Q=L[i].expense;

        while(Q!=NULL)

        {

        fout2<<Q->Date<<" "<<Q->money<<'\n';

        Q=Q->next;

        }

        fout2<<"#\n";

        }

        fout2.close();

       }

       void menu1(int choice[COUNT])

       {

        char s[5];

        cout<<"

相关栏目:百科