1,iOS arc 请问大侠们这行代码输出什么为什么这样输出结果是:string如果将strongStr复制给__weak实例变量,[mw_shl_code=c,true]- (void)viewDidLoad{ [super viewDidLoad]; NSLog(@"weakStr:%@",weakStr);}[/mw_shl_code]此时输出结果为null输出结果是:string如果将strongStr复制给__weak实例变量,[mw_shl_code=c,true]- (void)viewDidLoad{ [super viewDidLoad]; NSLog(@"weakStr:%@",weakStr);}[/mw_shl_code]此时输出结果为null
2,iOS KVC的理解与crash场景实现原理:KVC的赋值本质上只是调用了属性的setter方法 , setter方法会按照setKey、_setKey、setIsKey的优先级进行调用,还没有,则按_key、_isKey、key、isKey查找成员变量 。如果accessInstanceVariablesDirectly返回NO , 则不会查找_key、_isKey、key、isKey,会直接调用- (void)setValue:(id)value forUndefinedKey:(NSString *)key 。若查找到isKey还是没找到,也会调用(void)setValue:(id)value forUndefinedKey:(NSString *)key , 该方法默认会抛出异常 。crash的场景:key 不是对象的属性,造成崩溃 。keyPath 不正确,造成崩溃 。key 为 nil , 造成崩溃 。value 为 nil , 为非对象设值,造成崩溃:[objc setValue:nil forKey:@"age"];crash的防护:load方法中对setValue: forUndefinedKey:和valueForUndefinedKey方法做方法替换,判断key或value为nil时return;
3,iCloud 是如何工作的简单介绍iCloud原理被冠以 iOS 5 最重要更新之一的 iCloud 到底是如何为用户服务的呢?下面带果迷们一起了解一下 iCloud 的内部构造 。iCloud 最简单的存在形式其实就是一个特定的文件夹,它位于 iOS 设备的/private/var/mobile/Library/Mobile Documents/目录下 。该目录中保存有各应用共享至云端的所有应用数据 。应用程序对该目录有部分读写权限,该权限是开发人员特有的 。对于密码钥匙串,开发人员可以在各应用间共享云端数据 。比如,X 公司开发的所有应用可以共享、查看以及更新相同的文件集 。你无法共享你开发者账户以外的数据,所以我的应用无法看到 X 公司的文件,反之亦然 。iOS 系统监控着 Mobile Documents 文件夹 。当文件被更改,设备会自动的将这些更改上传至云端 。从而这些更改就可以传输至同一账号绑定的所有设备上 。这些操作都由本地操作系统服务进行处理,应用程序不直接参与其中 。相反,应用程序通过订阅不同种类的通知来让应用知道最新发生的更改 。然后,它们可以通过对比本地和 iCloud 端的数据差异从而来处理数据版本冲突 。至于开发者如何做就是他们的事了 。他们可以选择“最近更改有效”策略 。或者他们可以结合一些其他方式的更改 。应用程序的职责就在于确保不同硬件设备单元上的数据保持一致,同时也需要可用的网络连接来处理这种一致性 。当用户失去网络连接的时候 , 麻烦事就来了 。比如,你也许在没有网络连接的航班上编辑待办事项,与此同时你的伴侣在他或她所在的城市正在更新同一份待办事项 。开发者们为此工作了数月,研究如何在同时接受双方修改的前提下结合这些更改并更新目标文件的策略 。最后,iCloud API 接口方式或许会很少 。它实际上就只是一个异地同步的存储文件夹 。【ioskvc实现原理,iOS arc 请问大侠们这行代码输出什么为什么这样】
4 , iOS中的KVC简介Key-Value Coding俗称"键值编码" , 苹果官方简称这个模式为KVC编码模式 , 也就是说可以通过一个Key去访问某一个属性 , 或者给对象去赋值,而不需要去明确存取方法,这样就可以动态的访问和修改对象的属性,而不是在编译的时候去确定,这也是iOS开发中的一大便利,其实有很多的框架和功能是用KVC去实现的,这个技术存在已经很长时间了,在网上也有很多相关的教程去教童鞋们如何去使用KVC,在这里,我们就只是简单的介绍一下KVC的底层实现和使用方法 。从苹果官方对KVC的解释来看,其实KVC在Fundation框架中占有很高的地位,诸如Core-Data之类的框架都使用到了KVC技术,我们在开发中可能常见的API有:NSKeyValueCoding类别中还有其他的一些比较重要方法,如下:说起KVC的执行流程,我们有很多初级工程师都不大清楚,只知道KVC是如何使用的,而不知道KVC是怎么Key的寻找策略的 。下图我们借鉴了MJ老师的两幅PPT来解释上图我们可以看到简单说KVC机制在设值的时候会按照 set<Key>: 》_set<Key> 》_<key> 》_is<Key> 》<key> 》 is<Key> 顺序搜索成员并进行赋值操作,但是如果开发者重写了类方法+ (BOOL)accessInstanceVarialbesDirectly并且让其返回NO,这样在搜索的时候会直接从步骤 1跳转到步骤5。举一个例子,我们先创建一个Person类然后用KVC赋值最终在控制台打印的结果是当调用valueForKey:方法时,KVC对key的搜索顺序有点不同于setValue:forKey:方法,大致步骤如下:如最终打印为上述可以看出,当Key查找不到值的时候会走 valueForUndefinedKey 方法中抛出异常类的成员变量有可能是自定义类或其他复杂数据类型,对这种成员变量可以先用KVC获取该属性,然后再用KVC来获取这个自定义类的属性,这样一层层去获?。?但这样比较繁琐 。对此KVC提供一个解决方案,就是键路径keyPath , 顾名思义就是按照路径寻找key 。主要有两个以下两个方法:在上述Person中我们创建一个Cat类在Cat类中我们创建一个属性 name我们如果需要用KVC对Person对象中Cat对象赋值的话 , 我们就必须用到KeyPath了KVC对于keyPath的搜索机制第一步就是分离key,用小数点.来分割key , 然后再像普通key一样按照上面介绍的顺序搜索 。使用KVC过程中最常见的异常就是不小心使用了错误的key,或者在设值中不小心传了nil的值 , KVC有专门的方法处理这些异常 。该方法返回一个可变有序数组 。对于无序的容器,可以用以下方法:该方法返回一个可变的无序集合 。同时他们也有对应的keyPath版本:当NSDictionary对象使用KVC时,valueForKey:的表现行为和objectForKey:一样,使用valueForKeyPath:可访问多层嵌套的字典会方便点,在KVC中有两个关于NSDictionary的方法:当开发者需要验证能不能用KVC设定某个值时 , 就需要在进行KVC赋值前验证值value的有效性,API文档里面提供下面的方法进行判断值的有效性 。该方法的工作原理:先找一下你的类中是否实现了方法-(BOOL)validate<Key>:error:,如果实现了就会根据实现方法里面的自定义逻辑返回NO或者YES,如果没有实现这个方法,则系统默认返回就是YES 。输出结果为这里首先调用方法 [self validateValue:&value forKey:key error:&error] ;,这里,由于我实现了方法-(BOOL)validatePersonName:(id *)value error:(out NSError * _Nullable __autoreleasing *)outError,所以就在这里进行值value有效性的判断,这里 [name isEqualToString:@"小明"] 我就给返回YES,否则就返回NO 。KVC在iOS开发中非常的灵活,提供了开发者更多的赋值和取值操作的选择,它的有点明显,缺点也有 , 如果key只写错 , 编写的时候不会报错,但是运行的时候会报错 , 在实际开发中需要开发者时刻小心自己输入的键值,也时刻提醒着开发者一旦使用KVC就要做容错处理 。5,ios越狱的详细工作原理iphone有着3个不同的ROM,但是都叫FLASH的,都是可以不加电压不拆出来就可以刷的!一个是类似硬盘功能的rom,一个是基带的rom,一个是BOOTLOADER和iboot这些在一起的ROM,也就是机器的引导类似 。越狱的过程是这样:将iphone进入DFU模式,利用XX程序引导iboot,然后向内存注入某个类minilinux,将他加载在iphone的内存中,划分一段为ramdisk,再引导这个ramdisk的/etc/fstab,将原来的系统盘加载进去 , 取得系统读写权限 , 改变整个目录的读写权限和属性(因为iphone的MAC OS就是一个UNIX),然后将自己添加的命令和功能写进系统盘中,达到XX的目的 。当越狱一成功,断电重启,内存中的ramdisk也就不见了,引导权回到了硬盘里面的操作系统了,所以 , 越狱没什么,就是提高系统使用的权限,让你可以装些东西而已 。但是越狱造成系统的不稳定,还是有可能发生的 。这个就是类似你电脑的硬盘,懂计算机知识的人都知道,硬盘中如果你重装系统然后搞点什么系统XX,类似vista的OEM欺骗,是完全没问题的 。XX失败,重新来过 。所以刷固件后的越狱是不会造成不可逆的 。或者本身的软件冲突,会造成白苹果 。唯一不可逆的只是你的资料备份问题 。关于bootloader的rom,其实是擦写不了的,也无法注入什么东西,唯一的办法是改变运行的进程,类似劫持 。所以,只能利用bug , 没bug的话,基本无法入手 。也就无法取得基带ROM的写入权限 。BL和iboot是不一样的 。。。。BL管基带和系统通信的借口 。iboot只管系统 。越狱看iboot,基带看BL 。所以,, , BL和iboot是改不了的 。1代iphone的BL不是改,是利用脚本,搞漏洞,达到刷自制基带的目的 。而2代的BL , 5.8也是这个道理,但是刷的是官方基带,配合软解程序 。黄雪和超雪说白了就是一个工作在seczone和操作系统中的小程序,也就是一个超级软卡贴 。所以也没变化任何程序(注入式进程)为什么新系统出来了叫大家别越狱,dev的意思是和这次3GS一样,怕把漏洞暴漏给苹果了 。所以才那样说了那番话,只要有时间肯定搞的定了你唯一的担心不在于越狱,iphone也可以刷坏的,有一定机率可以在刷官方固件时把基带字库刷坏,但是还没见过把“硬盘”刷坏的 。基带那个ROM就是字库存在的地方,手机维修人员称的“字库”是指程序存储器(Flash) 。也是可以刷的俗称硬降BL和iboot是不一样的 。BL管基带和系统通信的一个通道,在系统运行时,BL也在不断地运行,检查基带的变化,生怕过程任何企图XX了基带 。iboot其实就是DFU模式,恢复模式都集中在这里 。这2个都是整合在一起的 。iOS越狱原理:iPhone、iPad等设备都有3个可以不加电压不拆就可以刷新内容的rom 。破解就是对三处的rom进行文件的替换和刷新达到欺骗硬件并引导进入非官方应用的目的 。三个rom分别是类似硬盘功能的rom、基带的rom以及BOOTLOADER和iboot这些在一起的ROM 。越狱的过程是这样:将iPhone进入DFU模式,利用破解程序引导iboot,然后向内存注入某个类minilinux,将他加载在 iPhone的内存中,划分一段为ramdisk,再引导这个ramdisk的/etc/fstab,将原来的系统盘加载进去,取得系统读写权限 , 改变整个目录的读写权限和属性(因为iphone的MAC OS就是一个UNIX系统),然后将自己添加的命令和功能写进系统盘中,达到破解的目的 。当越狱一成功,断电重启,内存中的ramdisk也就不见了,引导权 回到了硬盘里面的操作系统了,但是系统使用的权限已经被提升,让你可以装些非官方的app应用 。原理:越狱的过程是这样:将iphone进入dfu模式,利用xx程序引导iboot,然后向内存注入某个类minilinux,将他加载在iphone的内存中,划分一段为ramdisk,再引导这个ramdisk的/etc/fstab,将原来的系统盘加载进去,取得系统读写权限,改变整个目录的读写权限和属性(因为iphone的mac os就是一个unix),然后将自己添加的命令和功能写进系统盘中,达到xx的目的 。当越狱一成功 , 断电重启,内存中的ramdisk也就不见了,引导权回到了硬盘里面的操作系统了,所以,越狱没什么,就是提高系统使用的权限,让你可以装些东西而已 。但是越狱造成系统的不稳定,还是有可能发生的 。基本介绍:越狱是指开放用户的操作权限,使得用户可以随意擦写任何区域的运行状态,只有越狱成功后iphone的文件系统才处于可读写(rw)状态,可以安装和运行未经过官方认证的第三方程序、插件 。工作原理 。。。去论坛找找吧 。。。越狱是指利用iOS系统的某些漏洞,通过指令取得到iOS的root权限,然后改变一些程序使得iOS的功能得到加强,突破iOS的封闭式环境 。iOS在刚刚买来的时候,是封闭式的 。作为我们普通的用户,是无法取得到iOS的root权限的,更无法将一些软件自己安装到手机中 。我们只能通过iTunes里的iTunes Store购买一些软件(当然也有免费的) , 然后通过Apple认可的方式(用iTunes连接并同步),将我们合法得到的软件复制如手机 。但这种方式就把我们广大用户牢牢地桎梏在苹果的管辖范围内 。一些好用的软件,但并不一定符合Apple利益,它们就无法进入iTunes Store 。比如我们无法在iOS上安装SSH,无法复制iOS中的文件,更无法安装更适合我们的输入法 。这些软件,都需要用到更高级别的权限,苹果是不允许的 。为了能够更好地使用我们的iPad , 我们要越狱 。越狱不是必须的,但越了狱的手机使用起来会更爽、更方便、更好玩 。越狱后,能够免费使用很多软件 , 更能够使手机的易用性进一步增强 。1、可以安装各种破解软件,使你不用付费就可以使用需要的软件及游戏2、安装各种常用插件,让你更好的掌控iphone,如:电话拦截,流量监控软件,后台内存清理,修改输入法 , 修改改主题3、越狱后可以删除iphone自带应用程序,删减掉那些没用且占用内存,影响机器速度的各种程序4、浏览系统文件夹 , 删除垃圾文件,扩大手机容量,加快手机运行速度5、手机优化,使您的手机运行速度更快6,weak的实现原理是什么 ios一、问题背景: 程序已经做好,ad hoc 及 app store 的profile在distribution 下均顺利build通过 。但传到app store 的时候却都总是说有签名错误 。程序本身没有任何问题,这个我非常肯定,所以各位兄弟回贴中所说的那些证书及profile的问题都不是原因 。弄了几个小时 没能解决后,又在网上查了下才发现,这是一个很莫名其妙的问题,在iphonedevsdk这个论坛上也有不少人遇到过 。跟我的一样,他们的程序本身都是签好了,就是传不上去 。有的问题出现在传新程序的时候,有的是出现在传update的时候;有的是用web方式传出错,用loader传成功,有的却又恰好相反 。最后解决它他们各自花了几个小时到几天不等的时间 。所以这可能是一个app store 上传程序的一bug,我可能是cocoachina里第一个遇到它的 , 但应该不会是最后一个,希望好运的兄弟们不会遇到 。二、痛苦的不断尝试: 按照在网上搜到的信息及各种各样的提示,我不断的试 。包括重做证书 , 重做profile,重新安装sdk等都已经试过,但一点效果都没有,给我的还是那段错误提示 。为了验证我机器上的证书及profile是否有效,我还特意做了一个"hello world"传了上去,结果是顺利通过,证明证书、profile及sdk的基本设置是没有问题的 , 问题就应该出在这个新程序的本身 。没有找到任何的原 因,我于是又新建了个项目,将那程序的内容全移到了新项目下,这个花了不少的时间,但得到的效果还一样 。有人说可能跟sdk的版本有关系,我 现在的版本应该是3.0 bate4对应的那sdk版本,算是比较老的了 。但我没办法升级,因为我的系统是10.5.5,后面的sdk大都要10.5.7以上的系统 。本来打算这个 程序完成后来升级系统的,没想却正好出现了问题 。同样我也没有办法尝试用loader来传 , 因为最新的loader同样需要10.5.7的系统支持,而旧 版本的loader已经不能使用 。三、以土办法来解决: 实在是没招了,但想到我的“hello world”是能顺利通过的,所以就横下心了,以一个全新的项目开始,小心的做没一个改动,每做一步大的改动都上传测试一下,做到最后,终于得到了通过, 真是不容易?。诩渖洗?0多次 。跟那些遇到过这个问题的老外一样,我也没有找到根本的原因所在 。四、总结: 1:几个无关: a:与你是用app store 还是ad hoc 的profile无关 。ad hoc 的profile build的二进制程序也是可以被app store接受的,我之前传的都是用ad hoc profile 编译的,并通过了审核 。表示怀疑的兄弟可以试着用ad hoc 编译一个简单的程序(如"hello world") 传到app store 上 , 绝对不会出现签名的错误 。当然前提是你没做错 。b:与clean、build、关闭xcode及重启电脑的次数无关 。以上的要有用做一次就有用了 。如果做了一次没用 , 那么做一百次也同样没用; c:如果电脑上的证书及profile能让其他的程序都通过,那么与它们无关; 2:几个可能有关: a:与程序名称(也就是.app前的名称)可能有关:比如中间有空格之类的可能有关系的 , 我最后传上去的那个就把空格给去掉了; b:与sdk的版本可能有关:有可能真是一个bug,老外有的出现这个情况后升级下sdk的ok了,但我没有条件升级; c:与上传方式可能有关:web和loader一个不行可以换一个试试,但我也没有条件试loader; d:与引用的库的路径可能有关:我用了320的一个库,后来稍微修改了一下路径ARC的本质ARC是编译器(时)特性,而不是运行时特性,更不是垃圾回收器(GC) 。Automatic Reference Counting (ARC) is a compiler-level feature that simplifies the process of managing object lifetimes (memory management) in Cocoa applications.ARC只是相对于MRC(Manual Reference Counting或称为非ARC,下文中我们会一直使用MRC来指代非ARC的管理方式)的一次改进,但它和之前的技术本质上没有区别 。具体信息可以参考ARC编译器官方文档 。ARC的开启与关闭不同于XCode4可以在创建工程时选择关闭ARC,XCode5在创建的工程是默认开启ARC,没有可以关闭ARC的选项 。如果需要对特定文件开启或关闭ARC,可以在工程选项中选择Targets -> Compile Phases -> Compile Sources , 在里面找到对应文件,添加flag:打开ARC:-fobjc-arc关闭ARC:-fno-objc-arc如图:ARC的修饰符ARC主要提供了4种修饰符,他们分别是:__strong,__weak,__autoreleasing,__unsafe_unretained 。__strong表示引用为强引用 。对应在定义property时的"strong" 。所有对象只有当没有任何一个强引用指向时 , 才会被释放 。注意:如果在声明引用时不加修饰符 , 那么引用将默认是强引用 。当需要释放强引用指向的对象时,需要将强引用置nil 。__weak表示引用为弱引用 。对应在定义property时用的"weak" 。弱引用不会影响对象的释放 , 即只要对象没有任何强引用指向,即使有100个弱引用对象指向也没用 , 该对象依然会被释放 。不过好在,对象在被释放的同时,指向它的弱引用会自动被置nil,这个技术叫zeroing weak pointer 。这样有效得防止无效指针、野指针的产生 。__weak一般用在delegate关系中防止循环引用或者用来修饰指向由Interface Builder编辑与生成的UI控件 。__autoreleasing表示在autorelease pool中自动释放对象的引用,和MRC时代autorelease的用法相同 。定义property时不能使用这个修饰符,任何一个对象的property都不应该是autorelease型的 。一个常见的误解是,在ARC中没有autorelease,因为这样一个“自动释放”看起来好像有点多余 。这个误解可能源自于将ARC的“自动”和autorelease“自动”的混淆 。其实你只要看一下每个iOS App的main.m文件就能知道,autorelease不仅好好的存在着,并且变得更fashion了:不需要再手工被创建,也不需要再显式得调用[drain]方法释放内存池 。以下两行代码的意义是相同的 。NSString *str = [[[NSString alloc] initWithFormat:@"hehe"] autorelease]; // MRCNSString *__autoreleasing str = [[NSString alloc] initWithFormat:@"hehe"]; // ARC 这里关于autoreleasepool就不做了 , 详细地信息可以参考官方文档或者其他文章 。__autoreleasing在ARC中主要用在参数传递返回值(out-parameters)和引用传递参数(pass-by-reference)的情况下 。__autoreleasing is used to denote arguments that are passed by reference (id *) and are autoreleased on return.比如常用的NSError的使用:NSError *__autoreleasing error; ?if (![data writeToFile:filename options:NSDataWritingAtomic error:&error]) ?NSLog(@"Error: %@", error); }(在上面的writeToFile方法中error参数的类型为(NSError *__autoreleasing *))注意,如果你的error定义为了strong型,那么 , 编译器会帮你隐式地做如下事情,保证最终传入函数的参数依然是个__autoreleasing类型的引用 。NSError *error; NSError *__autoreleasing tempError = error; // 编译器添加 if (![data writeToFile:filename options:NSDataWritingAtomic error:&tempError]) ?error = tempError; // 编译器添加NSLog(@"Error: %@", error); }所以为了提高效率 , 避免这种情况,我们一般在定义error的时候将其(老老实实地= 。=)声明为__autoreleasing类型的:NSError *__autoreleasing error;在这里,加上__autoreleasing之后,相当于在MRC中对返回值error做了如下事情:*error = [[[NSError alloc] init] autorelease];*error指向的对象在创建出来后,被放入到了autoreleasing pool中,等待使用结束后的自动释放,函数外error的使用者并不需要关心*error指向对象的释放 。另外一点,在ARC中,所有这种指针的指针 (NSError **)的函数参数如果不加修饰符 , 编译器会默认将他们认定为__autoreleasing类型 。比如下面的两段代码是等同的:- (NSString *)doSomething:(NSNumber **)value// do something}- (NSString *)doSomething:(NSNumber * __autoreleasing *)value// do something}除非你显式得给value声明了__strong,否则value默认就是__autoreleasing的 。最后一点,某些类的方法会隐式地使用自己的autorelease pool,在这种时候使用__autoreleasing类型要特别小心 。比如NSDictionary的[enumerateKeysAndObjectsUsingBlock]方法:- (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)// do stuffif (there is some error && error != nil)*error = [NSError errorWithDomain:@"MyError" ?code:1 userInfo:nil];}?}];?}会隐式地创建一个autorelease pool , 上面代码实际类似于:- (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)@autoreleasepool// 被隐式创建if (there is some error && error != nil)*error = [NSError errorWithDomain:@"MyError" ?code:1 userInfo:nil];}?}}];// *error 在这里已经被dict的做枚举遍历时创建的autorelease pool释放掉了 :(?}为了能够正常的使用*error,我们需要一个strong型的临时引用 , 在dict的枚举Block中是用这个临时引用,保证引用指向的对象不会在出了dict的枚举Block后被释放,正确的方式如下:- (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error__block NSError* tempError; // 加__block保证可以在Block内被修改[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)if (there is some error)*tempError = [NSError errorWithDomain:@"MyError" ?code:1 userInfo:nil];} ?}]if (error != nil)*error = tempError;} ?}
推荐阅读
- 安卓手机苹果主题ios9,为何无法修改主题?原因揭晓
- iOS版应用商店,苹果应用商店的详细网址
- 安卓 专业拍照软件,3.3版安卓手机摄像软件最新版本
- 安卓盒子手柄软件,安卓游戏手柄哪个才是你人生核心古迹?
- 超级星饭团安卓版,超级star饭团如何设置明星在线提醒?
- unity 安卓闪退原因,如何备份和恢复软件运作?
- 安卓 常亮,部分三星手机支持智能睡眠功能
- 安卓机,玩游戏最好买苹果苹果比安卓好但开源性不如安卓
- 安卓车载桌面主题,安卓系统手机应用下载安装完成!