欢迎来到皮皮网官网

【dnf遍历源码】【鬼吹灯源码】【自动源码分析】setlist区别源码_set.list.map区别

时间:2024-12-28 15:35:20 来源:记事本 php 源码

1.xcode调试心得
2.arraylist和linkedlist重大区别?
3.list与arraylist 区别

setlist区别源码_set.list.map区别

xcode调试心得

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

崩溃的区p区表现一般来说:

SIGABRT(好处理)

EXC_BAD_ACCESS(一般内存问题)

SIGBUS

SIGSEGV

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

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

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

App启动的流程

       上面的图的调用关系说明了App是怎么启动的,除了main方法,其他方法都是看不到的,默认封装到系统的鬼吹灯源码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是按钮对象,所以会崩溃,不能忽略警告

arraylist和linkedlist重大区别?

       1. ArrayList是实现了基于动态数组的数据结构,而LinkedList是基于链表的数据结构;

       2. 对于随机访问get和set,ArrayList要优于LinkedList,因为LinkedList要移动指针;

       3. 对于添加和删除操作add和remove,一般大家都会说LinkedList要比ArrayList快,因为ArrayList要移动数据。但是实际情况并非这样,对于添加或删除,LinkedList和ArrayList并不能明确说明谁快谁慢

       研究源码可以看出,ArrayList想要get(int index)元素时,直接返回index位置上的元素,而LinkedList需要通过for循环进行查找,虽然LinkedList已经在查找方法上做了优化,比如index < size / 2,则从左边开始查找,反之从右边开始查找,但是还是比ArrayList要慢。这点是毋庸置疑的。

       ArrayList想要在指定位置插入或删除元素时,主要耗时的是System.arraycopy动作,会移动index后面所有的元素;LinkedList主耗时的是要先通过for循环找到index,然后直接插入或删除。这就导致了两者并非一定谁快谁慢

       测试:

       import java.util.ArrayList;  

       import java.util.Collections;  

       import java.util.LinkedList;  

       import java.util.List;  

       /

*

       * @description 测试ArrayList和LinkedList插入的效率

       * @eson_     

       */

       public class ArrayOrLinked {   

       static List<Integer> array=new ArrayList<Integer>();  

       static List<Integer> linked=new LinkedList<Integer>();  

       public static void main(String[] args) {   

       //首先分别给两者插入条数据

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

       array.add(i);  

       linked.add(i);  

       }  

       //获得两者随机访问的时间

       System.out.println("array time:"+getTime(array));  

       System.out.println("linked time:"+getTime(linked));  

       //获得两者插入数据的时间

       System.out.println("array insert time:"+insertTime(array));  

       System.out.println("linked insert time:"+insertTime(linked));  

       }  

       public static long getTime(List<Integer> list){   

       long time=System.currentTimeMillis();  

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

       int index = Collections.binarySearch(list, list.get(i));  

       if(index != i){   

       System.out.println("ERROR!");  

       }  

       }  

       return System.currentTimeMillis()-time;  

       }  

       //插入数据

       public static long insertTime(List<Integer> list){  

       /

*

       * 插入的数据量和插入的位置是决定两者性能的主要方面,

       * 我们可以通过修改这两个数据,来测试两者的性能

       */

       long num = ; //表示要插入的数据量

       int index = ; //表示从哪个位置插入

       long time=System.currentTimeMillis();  

       for(int i = 1; i < num; i++){   

       list.add(index, i);     

       }  

       return System.currentTimeMillis()-time;  

       }  

       } 

       主要有两个因素决定他们的效率,插入的数据量和插入的位置。我们可以在程序里改变这两个因素来测试它们的效率。

       当数据量较小时,测试程序中,大约小于的时候,两者效率差不多,没有显著区别;当数据量较大时,大约在容量的1/处开始,LinkedList的效率就开始没有ArrayList效率高了,特别到一半以及后半的位置插入时,LinkedList效率明显要低于ArrayList,而且数据量越大,越明显。比如我测试了一种情况,在index=的位置(容量的1/)插入条数据和在index=的位置以及在index=的位置插入条数据的运行时间如下:

       在index=出插入结果:

       array time:4

       linked time:

       array insert time:

       linked insert time:

       在index=处插入结果:

       array time:4

       linked time:

       array insert time:

       linked insert time:

       在index=处插入结果:

       array time:4

       linked time:

       array insert time:7

       linked insert time:

       从运行结果看,LinkedList的效率是越来越差。

       所以当插入的数据量很小时,两者区别不太大,当插入的数据量大时,大约在容量的1/之前,LinkedList会优于ArrayList,在其后就劣与ArrayList,且越靠近后面越差。所以个人觉得,一般首选用ArrayList,由于LinkedList可以实现栈、队列以及双端队列等数据结构,所以当特定需要时候,使用LinkedList,当然咯,数据量小的时候,两者差不多,视具体情况去选择使用;当数据量大的时候,如果只需要在靠前的部分插入或删除数据,那也可以选用LinkedList,反之选择ArrayList反而效率更高。

list与arraylist 区别

       List和ArrayList的区别在于:

       1、在编程语言中ArrayList类是.Net Framework提供的用于数据存储和检索的专用类。List 类可以简单视之为双向连结串行,以线性列的方式管理物件集合。List类是ArrayList类的泛型等效类。

       2、ArrayList继承了IList接口,所以它可以很方便的进行数据的添加,插入和移除。List的大部分用法都与ArrayList相似,List类也继承了IList接口。

       3、在ArrayList中可以插入不同类型的数据。ArrayList会把所有插入其中的数据都当作为object类型来处理,这其中存在装箱与拆箱的操作,会对系统造成性能上的损耗。而List需要声明其数据的对象类型。声明后插入其他类型数据,IDE就会报错,且不能通过编译。

       4、在使用ArrayList中的数据来处理问题的时候,很可能会报类型不匹配的错误,即ArrayList不是类型安全的。而List已经声明过其数据的对象类型,是类型安全的,避免了前面讲的类型安全问题与装箱拆箱的性能问题。

       5、ListArray就可以被构造。而List不能被构造,但可以为List创建一个引用。

扩展资料:

       ä¸€ã€List泛型

       é€šè¿‡å…è®¸æŒ‡å®šæ³›åž‹ç±»æˆ–方法操作的特定类型,泛型功能将类型安全的任务从程序员转移给了编译器。不需要编写代码来检测数据类型是否正确,因为会在编译时强制使用正确的数据类型。减少了类型强制转换的需要和运行时错误的可能性。泛型提供了类型安全但没有增加多个实现的开销。

       äºŒã€è£…箱与拆箱的概念:

       1、装箱:就是将值类型的数据打包到引用类型的实例中 比如将int类型的值赋给object对象o

       int i=; object o=(object)i;

       2、拆箱:就是从引用数据中提取值类型 比如将object对象o的值赋给int类型的变量i

       object o=; int i=(int)o;

       3、装箱与拆箱的过程是很损耗性能的。

       å‚考资料:拆箱——百度百科

copyright © 2016 powered by 皮皮网   sitemap