随着iOS平台开发的职位的增加,笔试、
面试也越来越有“套路”,这里我总结了一些面试题,多数是Objective-C的基础知识,适合于面试新人,答案是我自己答的,不准确的地方,欢迎指出。
1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?
Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。
2.#import 跟#include 又什么区别,@class呢, #import<> 跟 #import”"又什么区别?
#import 是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导 入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系 统的头文件,#import””用来包含用户头文件。
3. 属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用?
readwrite 是可读可写特性;需要生成getter方法和setter方法时
readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变
assign 是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;
retain 表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;
copy 表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时。
nonatomic 非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic
4.写一个setter方法用于完成@property (nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy)NSString *name
- (void) setName:(NSString*) str { [str retain]; [name release]; name = str; } - (void)setName:(NSString *)str { id t = [str copy]; [name release]; name = t; } |
5.对于语句NSString*obj = [[NSData alloc] init]; obj在编译时和运行时分别时什么类型的对象?
编译时是NSString的类型;运行时是NSData类型的对象
6.常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int
object-c的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;NSInteger是基本数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是Long。
7.id 声明的对象有什么特性?
Id 声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;
8.Objective-C如何对内存管理的,说说你的看法和解决方法?
Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
9.内存管理的几条原则时什么?按照默认法则.那些关键字生成的对象
需要手动释放?在和property结合的时候怎样有效的避免内存泄露?
谁申请,谁释放
遵循Cocoa Touch的使用原则;
内存管理主要要避免“过早释放”和“内存泄漏”,对于“过早释放”需要注意@property设置特性时,一定要用对特性关键字,对于“内存泄漏”,一定要申请了要负责释放,要细心。
关键字alloc 或new 生成的对象需要手动释放;
设置正确的property属性,对于retain需要在合适的地方释放,
10.如何对iOS设备进行性能测试?
Profile-> Instruments ->Time Profiler
11.看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为什么?
======================================================= NSMutableArray* ary = [[NSMutableArray array] retain]; NSString *str = [NSString stringWithFormat:@"test"]; [strretain]; [aryaddObject:str]; NSLog(@"%@%d",str,[str retainCount]); [strretain]; [strrelease]; [strrelease]; NSLog(@"%@%d",str,[str retainCount]); [aryremoveAllObjects]; NSLog(@"%@%d",str,[str retainCount]); ======================================================= |
从今年过完春节过来后,公司的产品步骤从C/S转变为B/S,之前B/S的
测试经验较少,而且产品调整比较快,一下子没有反应过来测试上应该做的调整。
根据项目的推进,对
web测试上可测试点进行汇总,老生常谈的问题,但是还是想自己总结下:
1.功能测试:毋庸置疑,这是测试的根本。
2.浏览器兼容测试:可根据产品使用者的习惯以及目前市场上浏览器的排行榜进行浏览器种类测试的选择。
3.网址测试:对此项测试印象很深刻,但是我发现好多人根据不在乎此测试,或者是根据觉得不应该测试,如果有这种观点的应该及时改正,哈哈。网址也是咱们开发出来的嘛!
4.UI界面友好性测试:俗话说第一印象很重要,如果没有漂亮的界面,好多用户是懒的看的,好的界面既要符合公司的发展,也要符合用户的眼光,很是佩服UI设计人员。
5.数据库测试:声明,这里说的不是对
数据库进行的压力测试,而是数据连接测试,如果数据存储出问题了,那可不是小事儿。其实之前做c/s的时候没有什么感觉,也是这次的项目给我很深刻的印象。
6.连接测试:产品中含有死链、坏链等无效的链接地址,是要给页面的响应速度增加负担的,这方面其实还是要注意下。xenu目前用的是这个小工具。
7.单个页面响应速度:明确了单个的页面响应速度也同样能知道那种元素对页面的影响最大。目前使用工具为httpWatch。发现此工具的作用还是蛮多的,应该好好研究下。
8.自动化测试:稳定的产品比较适用,对测试人员的技术要求也比较高,目前的工具也比较多开源的破解的嘿嘿。正在
学习中;但是有一点很重要不是所有的功能都适用于自动化,所以设计上还是要思考清楚。
9.性能测试:压力测试、负载测试、效率测试等等
以上是接触B/S后的感受,再次记录一下,时间长些后会有些补充,没有什么逻辑,
随笔而已,其实什么也不是那么容易可以搞定的,安静下来,多用用心,多用用脑,我相信我可以。
为增强自信心而写代码
关于
单元测试,其作用我认为更多的是增强开发者的信心,以及作为代码的执行文档(额外的效果)。也就是说,编写单元测试首先是开发者的责任,其次单元测试的粒度由程序员的自信心决定。
"老板为我的代码付报酬,而不是测试,所以,我对此的价值观是——测试越少越好,少到你对你的代码质量达到了某种自信(我觉得这种的自信标准应该要高于业内的标准,当然,这种自信也可能是种自大)。如果我的编码生涯中不会犯这种典型的错误(如:在构造函数中设了个错误的值),那我就不会测试它。我倾向于去对那些有意义的错误做测试,所以,我对一些比较复杂的条件逻辑会异常地小心。当在一个团队中,我会非常小心的测试那些会让团队容易出错的代码。"
--XP和TDD的创造者Kent Beck如是说。
由过去的经验,我认同上述的观点,并且认为不应该将单元测试作为银弹。甚至项目经理应该忘记有单元测试这回事,干脆把那当做程序员的乐趣就好了,然后该有的测试流程和规范必须要求到。
不要违反原则
单元测试需遵守的关键原则是:
1、单元测试应该是可重复的
2、单元测试应该是独立的
3、单元测试是快速执行的
以下为一个坏的例子。
部门的技术主管一直希望找到一种方法可以普遍提高开发人员的代码水平,以及减少bug和改善设计,这恰恰是单元测试所擅长的。所以我们配合持续集成的实践,在后来的项目中严格要求单元测试。
不得不说,在经过一段时间的抵触后,大家还是非常喜欢的。因为我们的产品清单上有专门的单元测试时间,并且大家也开始尝到甜头--容易犯的小错少了。
但是在我们还来不及欢呼的时候,问题出现了,而且很棘手。
我们的项目大都是关于数据存储的,比如简单的新增、复杂的查询、显示报表等等。而我们的单元测试其实就是冒烟测试,并且还是不合格的单元测试。原因是我们使用
数据库的数据作为输入,众所周知,这些数据很容易被修改,故我们的单元测试是不可能具有可重复性。另外,我们的单元测试也不是独立的,因为我们非常依赖数据存储层。
从以上的描述,你可能猜到,没错,我们的开发人员大多都很初级,经常犯得错误就是关于sql的编写,ibatis的使用语法之类的错误。也就是说他们最不自信的地方就是语法或者工具的使用。
让单元测试变成可重复的相对简单,使用dbunit之类的工具可以轻松的达到,即使这个工具有时也会出错,比如oracle的Large Objec类型就会报错。但是对数据存储层的依赖就不能避免了,因为这恰恰是我们要测试的。而相比时间而言,前两个因素又显得不那么重要了。
在项目中,我们对每个dao层的方法都写了单元测试,有的单元测试花费的时间甚至比写代码的时间要多。结果是我们的代码确实是可用的,但是时间却比想象的多得多。比如由A来编写接口,然后由另外一个人B来编写页面,然后由B调用A的接口。花费的时间=编写接口+编写页面+2*调用接口时间(这个名称不怎么好,但是在海没有发现合适的名称时,还是让我们暂时使用它吧)。调用接口时间是指两个人座到一起,A告诉B如何调用他的接口的时间,加上刚好出了问题,A为了方便直接在B的电脑上修改花费的时间。这里的时间都是两份的。
而我们的项目执行一次单元测试至少要10分钟左右,而且还会报错,因为不可重复性,有时它可以执行成功,有时它并不能。现在我们要花费的时间变成编写接口+编写页面+2*调用接口的时间+n*10分钟。
之前说了,我们要求单元测试时为了保证接口是可用的,单元测试并不是唯一的方式。假设我们启动项目(5分钟),点击页面进入页面(每次0.5分钟),然后出错查看信息,解决问题(M分钟)。相比之下,使用单元测试则是启动10分钟,出错,设置打印信息,然后启动(10分钟),再设置打印信息。直至发飙。。。
现在,你应该知道我们的痛苦了。
从今年过完春节过来后,公司的产品步骤从C/S转变为B/S,之前B/S的
测试经验较少,而且产品调整比较快,一下子没有反应过来测试上应该做的调整。
根据项目的推进,对
web测试上可测试点进行汇总,老生常谈的问题,但是还是想自己总结下:
1.功能测试:毋庸置疑,这是测试的根本。
2.浏览器兼容测试:可根据产品使用者的习惯以及目前市场上浏览器的排行榜进行浏览器种类测试的选择。
3.网址测试:对此项测试印象很深刻,但是我发现好多人根据不在乎此测试,或者是根据觉得不应该测试,如果有这种观点的应该及时改正,哈哈。网址也是咱们开发出来的嘛!
4.UI界面友好性测试:俗话说第一印象很重要,如果没有漂亮的界面,好多用户是懒的看的,好的界面既要符合公司的发展,也要符合用户的眼光,很是佩服UI设计人员。
5.数据库测试:声明,这里说的不是对
数据库进行的压力测试,而是数据连接测试,如果数据存储出问题了,那可不是小事儿。其实之前做c/s的时候没有什么感觉,也是这次的项目给我很深刻的印象。
6.连接测试:产品中含有死链、坏链等无效的链接地址,是要给页面的响应速度增加负担的,这方面其实还是要注意下。xenu目前用的是这个小工具。
7.单个页面响应速度:明确了单个的页面响应速度也同样能知道那种元素对页面的影响最大。目前使用工具为httpWatch。发现此工具的作用还是蛮多的,应该好好研究下。
8.自动化测试:稳定的产品比较适用,对测试人员的技术要求也比较高,目前的工具也比较多开源的破解的嘿嘿。正在
学习中;但是有一点很重要不是所有的功能都适用于自动化,所以设计上还是要思考清楚。
9.性能测试:压力测试、负载测试、效率测试等等
以上是接触B/S后的感受,再次记录一下,时间长些后会有些补充,没有什么逻辑,
随笔而已,其实什么也不是那么容易可以搞定的,安静下来,多用用心,多用用脑,我相信我可以。
最近几年,
云计算非常受欢迎,而在这种环境的影响下,
软件开发项目也变得非常流行。该技术未必适合每一个企业,但是,云计算并不是一时的流行而已。云计算的
软件测试功能为项目开发带了新的机遇,同时也带来了新的挑战。
云中软件测试的风险与安全问题
如下列举了一些在软件测试过程中应用云工具最常问到的几个问题。
云中测试和运行企业软件会带来哪些利益?
运用云工具,开发人员和测试人员可以拥有一些主动权。在内部测试以及其他环节上,他们拥有相同的基本功能。关键优势是云中测试可以提供更好地可扩展性。
与传统的云计算相比,扩展性可以让不同类型的公司都可以处理大型项目,对于中小型企业来说,更能凸显这种优势。当接到一个额外的而又不得不处理的测试任务时,开发团队可以运用现有的基础框架应对这种额外的测试服务。这样做可以为企业节省时间和节约资金,并将其投入到设备上,以及分配给短期的特殊项目。
除了可扩展性外,云基础设施可以让生产环境的测试和监控变得更加容易。应用程序可以检测出实际用户的数目。对于全球化应用程序来说,也应该进行充分的测试。当用户正在使用一个应用程序时,国际化和本地化方法可以帮助企业探测出用户的地理位置,并相应地调整用户体验。此外,实际生产环境中会出现一些潜在的问题和急需修正的情况,此时,云
功能测试可以向开发团队提供丰富的知识以应对如上情况。
有了云工具,测试团队再也不必等着IT才能开工。Rob Barry在一篇
文章中提到,用户反映有了虚拟的实验室后,解决问题的速度变得更快了。当质量保证专家们不再处理机器或者界面出现的IT问题时,他们也会放松放松。另外,IT可以节省更多的时间来处理一些潜在的却更加重要的问题。
有哪些风险或者缺点?
云测试环境中在责任和能力方面会出现风险。当不再使用本地工具时,可能会出现一些失控的情况。拥有一种外部媒介可以减少开发中IT人员的
工作时间,但是,只有当供应商能够迅速地解决出现的所有问题时,才会显现出其有利的一面。如果所出现的问题得不到解决,IT人员也不会去援助,因为,他们手边没有可以使用的工具。
可扩展性除了是云基础设施的一大优势外,它还展示了一些未知之事。我们也许不知道一个指定项目的规模比重,这样的话,云计算会引起高额的费用。没有正式的审批程序而建立了新的虚拟机器可能会引起意想不到的费用,特别是如果自动化方法没有缩减到应有的费用标准时,费用会更高。为了避免这些问题,测试团队可以而且应该使用云服务,研究云供应商的政策中出现争议的账单。
另外,云计算还会面临功能测试、数据管理、安全、个人隐私和可利用性等方面的挑战。企业必须判断出他们会面临哪些风险。对于一些企业来说,云测试的财务成本可能过高。面对如上所有的风险时,最重要的是,企业要非常好地掌握云功能,并知道如何最优化使用云功能。
有哪些安全问题?
企业应用程序必须具备安全性,但是,由于处于这种特殊环境下,这些应用程序就必须经过测试环境,而且要依托于云计算。我们要了解云计算的缺陷以及如何应对这些缺陷。
决策者应该考虑云计算中哪些数据能够被采用,特别是,当这些数据中包含用户信息时就更要谨慎。无论公司针对于安全性采取了什么措施,安装防火墙或者其他什么工具,我们都要解决安全隐患。
最近在研究
java代码的生命周期。这其中遇到一个java代码初始化的问题。
代码如下:
public class JvmTest { private static int count1; private static int count2 = 0; private static JvmTest JvmTest =new JvmTest(); public JvmTest() { System.out.println("JvmTest"); count1++; count2++; } public static JvmTest getInstance() { return JvmTest; } public static void main(String[] args) { System.err.println("count1=" + JvmTest.count1); System.err.println("count2=" + JvmTest.count2); } } |
这段代码运行之后的结果是什么呢?
如果你已经有答案了,请看下面这段代码:
public class JvmTest { private static JvmTest JvmTest =new JvmTest(); private static int count1; private static int count2 = 0; public JvmTest() { System.out.println("JvmTest"); count1++; count2++; } public static JvmTest getInstance() { return JvmTest; } public static void main(String[] args) { System.err.println("count1=" + JvmTest.count1); System.err.println("count2=" + JvmTest.count2); } } |
这段运行结果又是什么呢?
我开始对运行结果也比较疑惑,然后仔细分析了一下,问题就出在java代码的初始化上。因为这个
测试类是带有main函数的,它会在程序运行时即执行。所以这属于主动引用,这种情况会促使类的初始化。初始化过程中,在调用成员方法之前,它首先会按顺序对静态成员变量进行赋值,如果无值可赋就给一个默认值。说到这里我想上面两段代码的结果也就好解释了。
第一段首先count1和count2值都是0,一个是类加载过程中默认的0,一个是赋值为0,然后执行了new操作,对count1和count2进行自加,所以到这里,count1和count2的值都是1.而第二段则是先new操作对count1和count2都自加,变成1,然后再对count2进行赋值操作,所以count2的值又从1改成了0.
遇到的问题如下:数据库中存储了IP地址,以及IP地址掩码,需要将他们转化成CIDR格式的,并且不仅仅是将掩码转化成CIDR对应的数字的问题,需要将原有的IP地址转化成对应的网络地址,例如IP地址是58.247.221.238,掩码是255.255.255.252,需要将其转化为58.247.221.236/30。
解决方案:我们知道,将IP地址和掩码通过位与函数就能得到对应的网络地址.Google一下,找到了将IPv4地址转成数字以及转化回来的函数。有了这两个函数,再利用
Oracle 自带的bitand函数,问题就解决了。可以先将IP地址和掩码通过字符串转IP的函数转成数字,然后通过位与运算就能得到相应的网络地址对应的数字,再通过数字转字符串的功能,即得到对应的网络地址。至于/后面CIDR的数字,可以通过导入一张掩码和CIDR数字的对应表得到,不在详述.
实际例子如下: 返回58.247.221.236
Sql代码
select inttoip(BITAND(dottedQuadToNumber('58.247.221.238'),
ottedQuadToNumber('255.255.255.252'))) from dual
附: 将字符串转成数字的函数:
Sql代码
CREATE OR REPLACE function dottedQuadToNumber ( dottedQuad IN VARCHAR2) return number is Result NUMBER; begin Result:= (substr(dottedQuad , 1, (instr(dottedQuad , '.', 1, 1 ) - 1)) * 256 * 256 * 256 ) + (substr(dottedQuad , instr(dottedQuad , '.', 1, 1 ) + 1, instr(dottedQuad , '.', 1, 2 ) - instr(dottedQuad , '.', 1, 1 ) - 1) * 256 * 256 ) + (substr(dottedQuad , instr(dottedQuad , '.', 1, 2 ) + 1, instr(dottedQuad , '.', 1, 3 ) - instr(dottedQuad , '.', 1, 2 ) - 1) * 256 ) + (substr(dottedQuad , instr(dottedQuad , '.', 1, 3 ) + 1) ) ; return(Result ); end dottedQuadToNumber ; |
数字转成ip地址的函数:
Sql代码
CREATE OR REPLACE function inttoip(ip_address integer) return varchar2 deterministic is begin return to_char(mod(trunc(ip_address /256/ 256/256 ),256)) || '.'|| to_char(mod(trunc(ip_address/ 256/256 ),256)) || '.'|| to_char(mod(trunc(ip_address/ 256),256 )) || '.'|| to_char(mod(ip_address, 256)); end; |
1、调用 自带mail
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://admin@hzlzh.com"]];
2、调用 电话phone
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://8008808888"]];
iOS应用内拨打电话结束后返回应用
一般在应用中拨打电话的方式是:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://123456789"]];
使用这种方式拨打电话时,当用户结束通话后,
iphone界面会停留在电话界面。
用如下方式,可以使得用户结束通话后自动返回到应用:
UIWebView*callWebview =[[UIWebView alloc] init];
NSURL *telURL =[NSURL URLWithString:@"tel:10086"];// 貌似tel:// 或者 tel: 都行
[callWebview loadRequest:[NSURLRequest requestWithURL:telURL]];
//记得添加到view上
[self.view addSubview:callWebview];
还有一种私有方法:(可能不能通过审核)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"telprompt://10086"]];
3、调用 SMS
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://800888"]];
4、调用自带 浏览器 safari
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.hzlzh.com"]];
调用phone可以传递号码,调用SMS 只能设定号码,不能初始化SMS内容。
若需要传递内容可以做如下操作:
加入:MessageUI.framework
#import <MessageUI/MFMessageComposeViewController.h>
实现代理:MFMessageComposeViewControllerDelegate
调用sendSMS函数
//内容,收件人列表 - (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSArray *)recipients { MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease]; if([MFMessageComposeViewController canSendText]) { controller.body = bodyOfMessage; controller.recipients = recipients; controller.messageComposeDelegate = self; [self presentModalViewController:controller animated:YES]; } } // 处理发送完的响应结果 - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result { [self dismissModalViewControllerAnimated:YES]; if (result == MessageComposeResultCancelled) NSLog(@"Message cancelled") else if (result == MessageComposeResultSent) NSLog(@"Message sent") else NSLog(@"Message failed") } |
默认发送短信的界面为英文的,解决办法为:
在.xib 中的Localization添加一組chinese就ok了
PS:开始写这个系列的笔记:主要是对过去自己比较模糊的一些概念进行
测试,明确结果,提高自己
IOS 应用如果占用系统的内容过大(8GB),就会造成应用直接被系统以崩溃的形式关闭,一次控制应用占用的内存大小是非常重要的事情。
现在我们来看看,一个空的应用占据的内容的大小:
测试环境:xCode 5.0/IOS 5
启动一个空应用,占用的内存为 2.6MB,占据应用崩溃的阀值为 0.03%
1:关于导航条的 Push和popup的测试结果
[self.navigationController pushViewController:m_navanimated:YES];
[self.navigationController popViewControllerAnimated:YES];
对于
pushViewController ,会将对应的ViewController对象的引用计数器+1
popViewControllerAnimated 会将对应的ViewController对象的引用计数器-1
但是有一点需要明确的是,对于函数
-(void)dealloc
{
//Objects release here
[super deallco];
}
只有在该引用计数器的值==0的时候才会调用,这个是必须牢记的。
在执行函数[self.navigationController popViewControllerAnimated:YES];的时候,如果弹出的ViewController对应的引用计数器为0,那么也会执行dealloc 函数。
所以再使用
[self.navigationController pushViewController:m_navanimated:YES];
[self.navigationController popViewControllerAnimated:YES];
栈函数对的时候,为了释放内存,我们可以这么使用
Nav_1 *m_nav = [[[Nav_1 alloc] initWithNibName:nil bundle:nil] autorelease];
[self.navigationController pushViewController:m_nav animated:YES];
这样就最大限度的节省了宝贵的内存空间
有一段时间没有认真总结和写博客了
前段时间找
工作、进入工作阶段。比较少静下来认真总结,现在静下心来总结一下最近的一些心得
前言
AsyncSocket详解
AsyncSocket示例
一、前言
公司的项目用到了Socket编程,之前在
学习的过程当中,用到的更多的还是http请求的方式。但是既然用到了就必须学习一下,所以就在网上找一些例子,然后想自己写一个demo。可是发现很多写iOS Socket的博客并没有很详细的说明,也可能是大神们觉得其他东西都浅显易懂。
自己专研了一下,将自己的一些理解总结出来,一方面整理自己的学习思路,另一方面,为一些和我有同样困惑的小伙伴们,稍做指引。
二、AsyncSocket介绍
1)iOS中Socket编程的方式有哪些?
-BSD Socket
BSD Socket 是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制。而iOS系统其实本质就是UNIX,所以可以用,但是比较复杂。
-CFSocket
CFSocket是
苹果提供给我们的使用Socket的方式,但是用起来还是会不太顺手。当然想使用的话,可以细细研究一下。
-AsyncSocket
这次博客的主讲内容,也是我们在开发项目中经常会用到的。
2)为什么选择AsyncSocket?
iphone的CFNetwork编程比较艰深。使用AsyncSocket开源库来开发相对较简单,帮助我们封装了很多东西。
三、AsyncSocket详解
1??说明
在我们开发当中,我们主要的任务是开发客户端。所以详解里主要将客户端的整个连接建立过程,以及在说明时候回调哪些函数。在后面的示例代码中,也会给出服务器端的简单开发。
2??过程详解
1.建立连接
- (int)connectServer:(NSString *)hostIP port:(int)hostPort
2.连接成功后,会回调的函数
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
3.发送数据
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
4.接受数据
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
5.断开连接
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
主要就是上述的几个方法,只是说在真正开发当中,很可能我们在收发数据的时候,我们收发的数据并不仅仅是一个字符串包装成NSData即可,我们很可能会发送结构体等类型,这个时候我们就需要和服务器端的人员协作来开发:定义怎样的结构体。