1.项目经验html
2.基础问题ios
3.指南认识c++
4.解决思路程序员
ios开发三大块:web
1.Oc基础面试
2.CocoaTouch框架objective-c
3.Xcode使用数据库
--------------------编程
CocoaTouch设计模式
Media
Core Services
Core OS
--------------------
System Framework
OC的类声明,定义域
OC关键字定义为 @class
O-C特有的语句for(。。in 。。)迭代循环,其余的条件和循环语句和c同样
OC对面向对象的概述
(1)基类:NSOject
(2)通常的继承是单继承,使用协议@protocol 实现多重继承
(3)全部的函数都是虚函数
Id类型
OC中每一个目标均可以表达为id类型,泛型。能够认为是NSObject *或者 void Nil
等同于null,表示一个目标指针
类定义
Oc的类分为2个文件,
.h文件存放类,函数的声明(声明的关键字 @interfance @end)
.m文件存放类的具体实现(实现关键字)
对象和类的方法
“+” 表示类的方法
“-”表示对象的方法 -(int)返回值f 函数的名字: (int) x;参数(有个“:”表示有几个参数,从第二个参数起“:”前面必须加空格)
对于方法声明的讲解
“:”表示继承 @interface Dog : NSObject{} @end
“{}”之间只能写字段(如:int age),不能写函数
右括号和@end间接写的是函数
建立对象
Dog *dog=[Dog alloc] ; 一个类的名字 + alloc
初始化构造函数
[dog init]; 凡是以init…开头的都是构造函数
销毁对象
[dog release];
字段定义
三种做用域:@public @protected(保护,在类自己或者子类中) @private (只能在类的内部)
补充:缺省的是protected
函数所有用public
变量必须定义在类{}之间的地方
注:在c中函数和字段是能够重名的
类的声明
必须带“*” 即表示指针也表示引用 Dog(对象) * myDog (变量名)
访问 myDog.dog(变量名访问字段)或者使用空格
多参数方法
带两个参数(函数名为f::)
两种写法 -(float)f(int)x 【空格】 :(int)y 不提倡这种写法
(2)-(float)f(int)x 【空格】g:(int)y g:表示标签 (第一参数不能有标签,第一个函数名就至关于第一个参数的标签,是为了方便阅读)
如何调用方法
无参数
-(int)foo;
Int ret=[obj foo] 调obj的方法,没有参数,调方法的时候用[]
一个参数
-(int)foo:(int)a;
Int ret=[obj foo:10]
带标签
-(int)foo:(int)a andB(int)b;
Int ret=[obj foo:10 andB:2];
OC不是严格的函数重载
-(int)g:(int)x;
-(int)g:(folat)x;两个函数的函数名都为”g:” 在OC中是错误的,可是c中是可行
函数做用域声明
.h中定义的全部函数都是public类型的
私有化的解决方法
在.m文件中使用Categories
@property age
合成定义在.h文件中使用 编译器
=(1)”-(void)setAge:(int)newAge;” + “-(int) age;”
@synthesize 合成实现,编译器自动实现getter和setter函数
=(1)”-(void)setAge:(int)newAge{ age = newAge;}”+”return age;”
属性能够是
readwrite(缺省),readonl:
表示可读写(setter和getter函数均可以使用),readonly只能用getter
assign(缺省)、retain,copy
表示属性如何存储 assign至关于“=”表示赋值
Nonatomic(UI中经常使用)
表示不用考虑线程安全问题
getter=…,setter=…
从新设置getter函数和setter函数名
点语法
内部类age和点age(.age)不一样
直接访问age至关于访问age字段,
.age在等号左边至关于setter函数,在等号的右边至关于getter函数
例子:dog.age=200;展开成[dog setAge:200];
说明:
(1)age不是变量的名字,而是函数
(2)点语法在等号的左边表示设置函数(set…)
dogAge = dog.age;展开成 dogAge = [dog age]; (系统自动展开)
@class 与 #import :
import会包含这个类的全部信息,包括实体变量和方法,
而@class只是告诉编译器,其后面声明的名称是类的名称
在头文件中, 通常只须要知道被引用的类的名称就能够了。 不须要知道其内部的实体变量和方法,
因此在头文件中通常使用@class来声明这个名称是类的名称。
而在实现类里面,由于会用到这个引用类的内部的实体变量和方法,
因此须要使用#import来包含这个被引用类的头文件。
在编译效率方面考虑,若是你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,
如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面全部引用它的类都须要从新编译,
若是你的类有不少的话,这将耗费大量的时间。而是用@class则不会。
若是有循环依赖关系,如:A–>B, B–>A这样的相互依赖关系,若是使用#import来相互包含,那么就会出现编译错误,
若是使用@class在两个类的头文件中相互声明,则不会有编译错误出现。
因此,通常来讲,@class是放在interface中的,只是为了在interface中引用这个类,把这个类做为一个类型来用的。
在实现这个接口的实现类中,若是须要引用这个类的实体变量或者方法之类的,仍是须要import在@class中声明的类进来.
字符串
NSString: Cocoa中处理字符串的类
NSString型数据是特殊的NSString字面量,其指示标志是双引号内的字符串前的@,如@“Hi!”
NSString的stringWithFormat:方法就是经过格式字符串和参数来建立NSString的
+(id)stringWithFormat:(NSString *)format,...;
例子:
NSString *height;
Height=[NSString stringWithFormat:@”Your height is %d feet,%d inches”,5,11];
stringWithForat:(1)定义最后的省略号:能够接受对个以逗号隔开的其余参数
(2)“+”修饰的方法,为类方法,这个方法属于类对象(而不是类的实例对象)而且一般用于建立新的实例
是一个工厂方法,根据提供的参数建立新对象
“-”建立的大部分方法都是实例方法
NSString的实例方法length。返回的是字符串中的字符个数
使用 -(unsigned int)length:
Unsigned int length=[height length];
If([height length]>35){
NSLog(@”wow,you’re relly tall!”)}
比较字符串
isEqualToString:能够用来比较接收方和当作参数传递来的字符串。返回一个BOOL型数据表示字符串的内容是否相同,
-(BOOL)isEqualToString:(NSString *)aString;
具体的使用方法:
NSString *thing1=@“hello 5”;
NSString *thing2;
Thing2=[NSString stringWithFormat:@“hello %d”,5];
If([thing1 isEqualToString:thing2]){ NSLog(@”They are the same!);
注意:“==“运算符只判断thing1和thing2的这真数值,而不是他们所指的对象
两个字符串是否相等(等价性,两个字符串是否表明同一个事物)用isEqualToString
Compare:(区分大小写的比较的字符逐个字符的进行比较,,返回一个NSComparisonResult(就是一个enum型数据)来显示比较结果。如返回值是NSOrderedAscending,那么左侧的数值就小右侧的数值,即compare的目标在字母表中的排序位置比传递进来的字符串更靠前
Compare:options:
例子:-(NScomparisonResult)compare:(NSString *)string
options:(unsigned)mask;
options参数是一个位掩码。能够使用位或(bitiwise-OR)运算符(|)来添加选项标记。经常使用的选项以下:
NSCaseInsensitiveSearch:不区分大小写字符
NSLiteralSearch:进行彻底比较,区分大小写
NSNumericSearch:比较字符串的字符个数,而不是字符值,
可变数组
与NSString同样NSArray建立的是不可变对象的数组。补充类NSMutableArray,能够随意的田间和删除数组,经过类方法arrayWithCapacity来建立新的可变数组
+(id)arrayWithCapacity:(unsignde)numltems
删除特定索引处德对象。removeObject
枚举
NSEnumerator是Cocoa用来描述集合迭代运算的方式,需经过objectEnumerator像组组请求枚举器
-(NSEnumerator *)objcetEnumerator
从后向前浏览集合 reverseObjectEnumerator
能够用while循环,每次循环都向枚举器请求他的nextObject(下一个对象)
-(id)nextObject;返回nil时,循环结束
注:不能经过添加或删除对象这类方式来改变
字典:NSDictionary(也成为散列表或关联类表)使用的是键查询的优化存储方式
就是关键字及其定义的集合
NSDictionary在给定的关键字(一般是一个NSString字符串)下存储一个数值(能够是任何类型的对象
与NSString和NSArray同样只能使用NSMutableDictionary添加或者删除
建立字典dictionaryWithObjectsAndKeys;
+(id)dictionaryWithObjectsAndKeys:
(id)firstObject,…;
objectForKey:获取字典中得值,向方法传递以前用来存储改制的关键字
-(id)objectForKey:(id)aKey;
添加元素
-(void)setObject:forkey
NSNumber类来包装(即以对象形式实现)基本数据类型:
建立NSNumber对象:
+(NSNumber *)numberWithChar:(char) value;
+(NSNumber *)numberWithint:(int)value;
+(NSNumber *)numberWithFolatr (float) value;
+(NSNumber *)numberWithBOOL (BOOL) value;
对初学者来讲,Objective-C存在了不少使人费解的写法,实际上他们是很是优雅的。
程序员写的最多的就是函数以及调用本身写的或者别人写的函数。本文就从函数的角度来看下Objective-C的优雅之处。
C#和Objective-C同属于c系列语言。让咱们先看下C#的函数定义和调用,作个对比。
C#函数的定义:
函数的调用:
在让.net程序员看下Objective-C的定义:
若是你第一次看Objective-C,确定会琢磨不透上面的代码,怀疑是否是写错了。
对于上面这个函数的定义:
一、'-'表示这个函数是实例函数(相似非静态函数),'+'表示这个函数是类函数(相似静态函数)
二、(void)表示这个函数没有返回值。
三、函数名是'doIt:',而不是'doIt'
四、参数用空格隔开
五、参数类型写在括号中
六、参数份内部参数和外部参数,如电影名称,内部参数是:value,外部参数是:movieName
七、函数的一个参数没有外部参数的名称,有内部参数名。如:actorName。
调用:
从上面代码能够看出除了第一个参数,其他的参数均可以加上外部参数名称用于区别。
从上面能够看出Objective-C和C#区别很大,实在会令.net程序员费解。Objective-C函数设计的优雅之处在于即有内部参数名又有外部参数名,能够不用在再内部定义变量来存放函数的参数。
对Objective-C函数学习的一个简单总结。
1.编写OC程序:.m源文件
2.编译.m文件为.o目标文件:cc -c xxxx.m
3.连接.o文件为a.out可执行文件:cc xxxx.o -framework Foundation
4.执行a.out文件:./a.out
类定义// @implementation 和 @end
// 设计(定义)一个车类 // @implementation 和 @end // : NSObject :让Car这个类具有建立对象的能力(继承) @implementation Car : NSObject // 这个大括号里面只能写全部的属性 { // @public:让对象的属性能够被外面的指针访问,默认是私有的 @public int wheels; // 默认基本数据类型的初始值都是0 } // 在@end的前面,大括号{}外面写行为 // 给Car对象增长一个行为(方法) // 给对象增长一个行为,必须以减号 - 开头, 给类增长一个对象是+。 // OC方法中的小括号()只是主要扩住类型 - (void) run { // 访问车子对象内部的属性,直接用属性名就能够 NSLog(@"%i个轮子,%f时速的车子跑起来了!", wheels, speed); } + (Void) test { // 这是类方法。上面那个-号的是对象方法。 } @end
// 在OC中想执行一些行为,首先写个 [行为执行者 行为名称] // new这个行为执行完毕后,会返回这个对象的地址 Car *c = [Car new]; // 给c指向的车子对象的wheels属性赋值 c->wheels = 4; // 等价于 (*c).wheels = 4 // 给指针变量c指向的对象“发送”一条run消息,让这个对象执行run这个行为 [c run];
// 声明一个类 /* 1.类名 2.继承了NSObject 3.声明属性 4.声明方法(仅仅是声明,不须要实现) 5.实现和声明中的成员变量不能同名 */ @interface Book : NSObject { @public double price;// 这些属性称为对象的“成员变量” } // 声明一个方法(行为) - (void)reng; @end
// 定义(实现)一个类 /* 只用来实现@interface中声明的方法 */ @implementation Book - (void)reng { NSLog(@"%f的书被扔了!", price); }
- (void) fly { NSLog(@"i can fly, my age is %d", age); } // 一个参数对应一个冒号 // 冒号也是方法名的一部分 - (void)fly:(int)howHeight { NSLog(@"i can fly, my age is %d, my height %d", age, howHeight); } // 多个参数的状况。 withTime是方法名的一部分.times是参数名称 - (void)fly:(int)howHeight :WithTime(int)times { }
Person *p = [Person new]; [p fly]; [p fly:99]; [p fly:99 WithTime:10];
1. 函数属于整个文件,在文件的任意地方都能调用;对象的方法只属于这个对象,只有对象才能调用
2. 对象的方法只能声明在@infterface 和@end 之间,对象方法只能实如今@implementation 和@end之间。
函数的声明和定义能够写在任意地方,函数不能归某个类全部,只属于某个文件。
给指针变量所指向的对象发送一条消息(消息名称就是方法名),让那个对象执行相应的方法(动态)
一、Objective-C的类能够多重继承么?能够采用多个协议么?
答:不能够多重继承,能够采用多个协议。
二、#import和#include的区别是什么?#import<> 跟 #import""有什么区别?
#import能避免头文件被重复包含的问题:
1) 通常来讲,导入objective c的头文件时用#import,包含c/c++头文件时用#include。
使用include要注意重复引用的问题:
class A,class B都引用了class C,class D若引用class A与class B,就会报重复引用的错误。
2)#import 肯定一个文件只能被导入一次,这使你在递归包含中不会出现问题。
因此,#import比起#include的好处就是它避免了重复引用的问题。因此在OC中咱们基本用的都是import。
#import<> 包含iOS框架类库里的类,#import""包含项目里自定义的类。
三、Category是什么?扩展一个类的方式用继承好仍是类目好?为何?
答:Category是类目。用类目好,由于继承要知足a is a b的关系,而类目只须要知足a has a b的关系,局限性更小,你不用定义子类就能扩展一个类的功能,还能将类的定义分开放在不一样的源文件里, 用Category去重写类的方法,仅对本Category有效,不会影响到其余类与原有类的关系。
四、延展是什么?做用是什么?
答:延展(extension):在本身类的实现文件中添加类目来声明私有方法。
五、类实例(成员)变量的@protected,@private,@public声明各有什么含义?
@protected:受保护的,该实例变量只能在该类和其子类内访问,其余类内不能访问。
@private:私有的,该实例变量只能在该类内访问,其余类内不能访问。
@public:共有的,该实例变量谁均可以访问。
六、id声明的对象有什么特性?
Ø 没有 * 号
Ø 动态数据类型
Ø 能够指向任何类的对象(设置是nil),而不关心其具体类型
Ø 在运行时检查其具体类型
Ø 能够对其发送任何(存在的)消息
七、委托是什么?委托和委托方双方的property声明用什么属性?为何?
委托:一个对象保存另一个对象的引用,被引用的对象实现了事先肯定的协议,该协议用于将引用对象中的变化通知给被引用对象。
委托和委托方双方的property声明属性都是assign而不是retain
为了不循环引用形成的内存泄露。
循环引用的问题这样理解:
好比在main函数中建立了两个类的对象A和B,如今引用计数都是1。如今让A和B互相引用(A有一个属性是B对象,属性说明是retain;B有一个属性是A对象,属性说明是retain),如今两个对象的引用计数都增长了1,都变成了2。
如今执行[A release]; [B release]; 此时建立对象的main函数已经释放了本身对对象的全部权,可是此时A和B的引用计数都仍是1,由于他们互相引用了。
这时你发现A和B将没法释放,由于要想释放A必须先释放B,在B的dealloc方法中再释放A。同理,要想释放B必须先释放A,在A的dealloc方法中再释放B。因此这两个对象将一直存在在内存中而不释放。这就是所谓的循环引用的问题。要想解决这个问题,通常的方法能够将引用的属性设置为assign,而不是retain来处理。
八、浅拷贝和深拷贝区别是什么?
浅层复制:只复制指向对象的指针,而不复制引用对象自己。
深层复制:复制引用对象自己。
意思就是说我有个A对象,复制一份后获得A_copy对象后,对于浅复制来讲,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象自己资源仍是只有一份,那若是咱们对A_copy执行了修改操做,那么发现A引用的对象一样被修改,这其实违背了咱们复制拷贝的一个思想。深复制就好理解了,内存中存在了两份独立对象自己。
用网上一哥们通俗的话将就是:
浅复制比如你和你的影子,你完蛋,你的影子也完蛋
深复制比如你和你的克隆人,你完蛋,你的克隆人还活着。
九、内存管理的几条原则是什么?按照默认法则,哪些关键字生成的对象须要手动释放?哪些状况下不须要手动释放,会直接进入自动释放池?
• 当使用new、alloc或copy方法建立一个对象时,该对象引用计数器为1。若是不须要使用该对象,能够向其发送release或autorelease消息,在其使用完毕时被销毁。
• 若是经过其余方法获取一个对象,则能够假设这个对象引用计数为1,而且被设置为autorelease,不须要对该对象进行清理,若是确实须要retain这个对象,则须要使用完毕后release。
• 若是retain了某个对象,须要release或autorelease该对象,保持retain方法和release方法使用次数相等。
使用new、alloc、copy关键字生成的对象和retain了的对象须要手动释放。设置为autorelease的对象不须要手动释放,会直接进入自动释放池。
十、怎样实现一个单例模式的类,给出思路,不写代码。
• 首先必须建立一个全局实例,一般存放在一个全局变量中,此全局变量设置为nil
• 提供工厂方法对该全局实例进行访问,检查该变量是否为nil,若是nil就建立一个新的实例,最后返回全局实例
• 全局变量的初始化在第一次调用工厂方法时会在+allocWithZone:中进行,因此须要重写该方法,防止经过标准的alloc方式建立新的实例
• 为了防止经过copy方法获得新的实例,须要实现-copyWithZone方法
• 只需在此方法中返回自己对象便可,引用计数也不须要进行改变,由于单例模式下的对象是不容许销毁的,因此也就不用保留
• 由于全局实例不容许释放,因此retain,release,autorelease方法均需重写
十一、@class的做用是什么?
答:在头文件中, 通常只须要知道被引用的类的名称就能够了。 不须要知道其内部的实体变量和方法,因此在头文件中通常使用@class来声明这个名称是类的名称。 而在实现类里面,由于会用到这个引用类的内部的实体变量和方法,因此须要使用#import来包含这个被引用类的头文件。
• @class的做用是告诉编译器,有这么一个类,用吧,没有问题
• @class还能够解决循环依赖的问题,例如A.h导入了B.h,而B.h导入了A.h,每个头文件的编译都要让对象先编译成功才行
• 使用@class就能够避免这种状况的发生
十二、KVC是什么?KVO是什么?有什么特色?
• KVC是键值编码,特色是经过指定表示要访问的属性名字的字符串标识符,能够进行类的属性读取和设置
• KVO是键值观察,特色是利用键值观察能够注册成为一个对象的观察者,在该对象的某个属性变化时收到通知
1三、MVC是什么?有什么特性?
– MVC是一种设计模式,由模型、视图、控制器3部分组成。
– 模型:保存应用程序数据的类,处理业务逻辑的类
– 视图:窗口,控件和其余用户能看到的而且能交互的元素
– 控制器:将模型和试图绑定在一块儿,肯定如何处理用户输入的类
1四、定义属性时,什么状况使用copy、assign、retain?
使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float,double, char, 等等)
使用copy: 但愿得到源对象的副本而不改变源对象内容时,对NSString
使用retain: 但愿得到源对象的全部权时,对其余NSObject和其子类
15.属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么做用,在那种状况下用?
assign用于简单数据类型,如NSInteger,double,bool,
retain和copy用于对象,
readwrite是可读可写特性;须要生成getter方法和setter方法时
readonly是只读特性 只会生成getter方法 不会生成setter方法 ;不但愿属性在类外改变
assign是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;
retain表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;
copy表示赋值特性,setter方法将传入对象复制一份;须要彻底一份新的变量时。
nonatomic非原子操做,决定编译器生成的setter getter是不是原子操做,atomic表示多线程安全,通常使用nonatomic
16.id 声明的对象有什么特性?
答:Id声明的对象具备运行时的特性,便可以指向任意类型的objcetive-c的对象;
17.Objective-C如何对内存管理的,说说你的见解和解决方法?
答:Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
18.内存管理的几条原则时什么?
谁申请,谁释放
遵循Cocoa Touch的使用原则;
内存管理主要要避免“过早释放”和“内存泄漏”,对于“过早释放”须要注意@property设置特性时,必定要用对特性关键字,对于“内存泄漏”,必定要申请了要负责释放,要细心。
19.那些关键字生成的对象 须要手动释放?
答:关键字alloc 或new 生成的对象须要手动释放
20在和property结合的时候怎样有效的避免内存泄露?
答:设置正确的property属性,对于retain须要在合适的地方释放
21.如何对iOS设备进行性能测试?
Profile-> Instruments ->Time Profiler
22.Object-c的类能够多重继承么?能够实现多个接口么?
答:Object-c的类不能够多重继承;能够实现多个接口,经过实现多个接口能够完成C++的多重继承;
23.Category是什么?重写一个类的方式用继承好仍是分类好?为何?
答:Category是类别,通常状况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其余类与原有类的关系。
24.描述一下iOS SDK中如何实现MVC的开发模式
MVC是模型、试图、控制开发模式,对于iOS SDK,全部的View都是视图层的,它应该独立于模型层,由视图控制层来控制。全部的用户数据都是模型层,它应该独立于视图。全部的ViewController都是控制层,由它负责控制视图,访问模型数据
25. Object C中建立线程的方法是什么?若是在主线程中执行代码,方法是什么?若是想延时执行代码、方法又是什么?
线程建立有三种方法:使用NSThread建立、使用 GCD的dispatch、使用子类化的NSOperation,而后将其加入NSOperationQueue;在主线程执行代码,方法是 performSelectorOnMainThread,若是想延时执行代码能够用performSelector:onThread:withObject:waitUntilDone
2六、iPhone5 的屏幕分辨率大小为 1136* 640 ?
答:屏幕分辨率:用于量度位图图像内数据量多少的一个参数。一般表示成ppi(每英寸像素Pixel per inch)。屏幕物理尺寸不变,分辨率越高,每单位面积内包含的细节(像素点)越多。
2七、struct strA { int a; float b; char c; } expA;
printf("%ld",sizeof(expA)); 输出结果为 12 ?
该问题涉及编译器的“内存对齐”问题:
现代计算机中内存空间都是按照byte(字节)划分的,从理论上讲彷佛对任何类型的变量的访问能够从任何地址开始,但实际状况是在访问特定变量的时候常常在特定的内存地址访问,这就须要各种型数据按照必定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
对齐的做用和缘由:各个硬件平台对存储空间的处理上有很大的不一样。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其余平台可能没有这种状况, 可是最多见的是若是不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。好比有些平台每次读都是从偶地址开始,若是一个int型(假设为 32位)若是存放在偶地址开始的地方,那么一个读周期就能够读出,而若是存放在奇地址开始的地方,就可能会须要2个读周期,并对两次读出的结果的高低 字节进行拼凑才能获得该int数据。显然在读取效率上降低不少。这也是空间和时间的博弈。
一般,咱们写程序的时候,不须要考虑对齐问题。编译器会替咱们选择适合目标平台的对齐策略。固然,咱们也能够通知给编译器传递预编译指令而改变对指定数据的对齐方法。
可是,正由于咱们通常不须要关心这个问题,因此由于编辑器对数据存放作了对齐,而咱们不了解的话,经常会对一些问题感到迷惑。最多见的就是struct数据结构的sizeof结果,出乎意料。
对于结构体来讲,按成员中所占字节最大的是float类型,占用4个字节,一共有3个成员,因此总的占用字节为:4* 3 = 12.
可经过编译器命令来设定:
#progma pack (2)
2八、@property语法中readonly/readwrite,atomic/nonatomic的做用,@dynamic的做用?
@Property:Objective-C语言关键词,与@synthesize配对使用。xcode4.5以及之后的版本,@synthesize能够省略。
功能:让编译器自动编写一对与数据成员同名的方法声明来省去读写方法的声明。
声明property的语法为:
@property (参数1,参数2) 类型 名字;
如:@property(nonatomic,retain) UIWindow *window;
其中参数主要分为三类:
读写属性: (readwrite/readonly)
setter语意:(assign/retain/copy)
原子性: (atomicity/nonatomic)
各参数意义以下:
readwrite:同时产生setter\getter方法
readonly:只产生简单的getter,没有setter。
assign:默认类型,setter方法直接赋值,而不进行retain操做
retain:setter方法对参数进行release旧值,再retain新值。
copy:setter方法进行Copy操做,与retain同样
atomic:原子性,它没有一个若是你没有对原子性进行一个声明(atomic or nonatomic),那么系统会默认你选择的是atomic。
原子性就是说一个操做不能够被中途cpu暂停而后调度, 即不能被中断, 要不就执行完, 要不就不执行. 若是一个操做是原子性的,那么在多线程环境下, 就不会出现变量被修改等奇怪的问题。原子操做就是不可再分的操做,在多线程程序中原子操做是一个很是重要的概念,它经常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头。固然,原子性的变量在执行效率上要低些。
关于异步与同步:并不是同步就是很差,咱们一般须要同时进行多个操做,这时使用异步,而对于程序来讲,通常就是使用多线程,然而咱们不少时候须要在多个线程间访问共享的数据,这个时候又须要同步来保证数据的准确性或访问的前后次序。当有多个线程须要访问到同一个数据时,OC中,咱们能够使用@synchronized(变量)来对该变量进行加锁(加锁的目的经常是为了同步或保证原子操做)。
nonatomic:非原子性,是直接从内存中取数值,由于它是从内存中取得数据,它并无一个加锁的保护来用于cpu中的寄存器计算Value,它只是单纯的从内存地址中,当前的内存存储的数据结果来进行使用。在多线环境下可提升性能,但没法保证数据同步。
2九、OSI(Open System Interconnection)开放式系统互联参考模型 把网络协议从逻辑上分为了7层,试列举常见的应用层协议。
注意问的是应用层协议,有些同窗直接答了七层模型。
在开放系统互连(OSI)模型中的最高层,为应用程序提供服务以保证通讯,但不是进行通讯的应用程序自己。
Telnet协议是TCP/IP协议族中的一员,是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工做的能力。
FTP文件传输协议是TCP/IP网络上两台计算机传送文件的协议,FTP是在TCP/IP网络和INTERNET上最先使用的协议之一,它属于网络协议组的应用层。
超文本传输协议 (HTTP-Hypertext transfer protocol) 是分布式,协做式,超媒体系统应用之间的通讯协议。是万维网(world wide web)交换信息的基础。
SMTP(Simple MailTransfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式,它帮助每台计算机在发送或中转信件时找到下一个目的地。
时间协议(TIME protocol)是一个在RFC 868内定义的网络协议。它用做提供机器可读的日期时间资讯。
DNS 是域名系统 (Domain NameSystem) 的缩写,是因特网的一项核心服务,它做为能够将域名和IP地址相互映射的一个分布式数据库。
SNMP(Simple Network ManagementProtocol,简单网络管理协议)的前身是简单网关监控协议(SGMP),用来对通讯线路进行管理。
TFTP(Trivial FileTransfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69。
30、网络传输层协议中,基于TCP/IP协议和UDP/IP的链接有什么区别?
TCP:TransmissionControl Protocol 传输控制协议TCP是一种面向链接(链接导向)的、可靠的、基于字节流的运输层(Transport layer)通讯协议,由IETF的RFC 793说明(specified)。
UDP 是User DatagramProtocol的简称, 中文名是用户数据包协议,是OSI 参考模型中一种无链接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。
面向链接:是指通讯双方在通讯时,要事先创建一条通讯线路,其有三个过程:创建链接、使用链接和释放链接。电话系统是一个面向链接的模式,拨号、通话、挂机;TCP协议就是一种面向链接的协议。
面向无链接:是指通讯双方不须要事先创建一条通讯线路,而是把每一个带有目的地址的包(报文分组)送到线路上,由系统自主选定路线进行传输。邮政系统是一个无链接的模式,天罗地网式的选择路线,天女散花式的传播形式;IP、UDP协议就是一种无链接协议。
3一、简述MVC模式中M、V、C分别指代什么及发挥的做用?
MVC开始是存在于Desktop(桌面)程序中的,M是指数据模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。
视图是用户看到并与之交互的界面,视图没有真正的处理发生,无论这些数据是联机存储的仍是一个雇员列表,做为视图来说,它只是做为一种输出数据并容许用户操纵的方式。
模型表示企业数据和业务规则,模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据,因为应用于模型的代码只需写一次就能够被多个视图重用,因此减小了代码的重复性。
控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器自己不输出任何东西和作任何处理。它只是接收请求并决定调用哪一个模型构件去处理请求,而后再肯定用哪一个视图来显示返回的数据。
3二、声明@property的语法中,retain、copy、assign的含义及做用?试写出 @property中带retain和assign关键字,经过@synthesize自动生成的的合成存取方法(set、get方法)的实现代码。
getter分析:
@property (nonatomic, retain) test*aTest;
@property (nonatomic, copy) test*aTest;
等效代码:
-(void)aTest {
return aTest;
}
========== 貌似我是分割线 ===========
@property (retain) test* aTest;
@property (copy) test* aTest;
等效代码:
-(void)aTest
{
[aTest retain];
return [aTest autorelease];
}
setter分析:
@property (nonatomic, retain) test*aTest;
@property (retain) test* aTest;
等效于:
-(void)setaTest:(test *)newaTest {
if (aTest !=newaTest) {
[aTest release];
aTest = [newaTest retain];
}
}
========== 貌似我是分割线 ===========
@property (nonatomic, copy) test*aTest;
@property (copy) test* aTest;
等效于:
-(void)setaTest:(test *)newaTest {
if (aTest != newaTest){
[aTest release];
aTest = [newaTest copy];
}
}
3三、iOS中有哪些回调机制,并做简单的比较。
各类回调机制的比较:
1)目标动做对:当两个对象之间有比较紧密的关系时,如视图控制器与其下的某个视图。
2)代理:也叫委托,当某个对象收到多个事件,并要求同一个对象来处理全部事件时。委托机制依赖于某个协议定义的方法来发送消息。
3)通告机制:当须要多个对象或两个无关对象处理同一个事件时。
4)Block:适用于回调只发生一次的简单任务。
3四、列出在编码中哪些编码习惯有助于提升代码质量、软件性能和健壮性,减小程序崩溃。
#使用严格的命名规则(如匈牙利命名法)可以避免没必要要的类型转换错误。
#在编码前先设计好流程图或使用伪代码,清晰化整个设计意图。
#对本身的代码进行严格的单元测试(unit testing)。
单元测试是指对软件中的最小可测试单元进行检查和验证。如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中能够指一个窗口或一个菜单等。总的来讲,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程当中要进行的最低级别的测试活动,软件的独立单元将在与程序的其余部分相隔离的状况下进行测试。
#异常的处理
首先不要轻易使用异常的捕获,其次要尽量捕获具体的异常。对于异常的处理最好可以采用封装的方式,你们统一使用。这样能够保证异常处理的一致性也能够保证当异常出现时性能的稳定。
# 使用内省的方法检查方法的输入
#采用增量式的编程方式。
采用增量式编程和测试,会倾向于建立更小的方法和更具内聚性的类。你应该常常评估代码质量,并不时的进行许多小调整,而不是一次修改许多东西。在写了几行代码以后,就应该进行一次构建/测试。在没有获得反馈时,你不要走的太远。
#使用工具(如Instrument)来帮助检查内存泄漏、过早释放内存、CPU使用效率等问题。
#消除全部的编译警告,警告就是错误。
#写防护性的代码,使用内省的方法检查传入的参数。
3五、JSON中{ }表明_____,[ ]表明_____,试将下面的JSON串用OC对象表示出来:
{ "people": [
{ "firstName": "Brett","lastName":"McLaughlin", "email":"aaaa" },
{ "firstName": "Jason","lastName":"Hunter", "email": "bbbb"},
{ "firstName": "Elliotte","lastName":"Harold", "email": "cccc" }
],
“location”:”中华人民共和国”
}
JSON中{ }表明对象,数据结构为{key1:value1, key2:value2, key3:…… }
[ ]表明数组,与其余语言中的数组相似。
//
@interface People: NSObject
@property(nonatomic, copy) NSString* strFirstName;
@property(nonatomic, copy) NSString* strLastName;
@property(nonatomic, copy) NSString* strEmail;
@end
//
@interfaceJSonData : NSObject
@property(nonatomic, retain) NSMutableArray* arrPeople; // 存放People对象
@property(nonatomic, copy) NSString* strLocation;
@end
36. Object-C有多继承吗?没有的话用什么代替?
答:没有,cocoa 中全部的类都是NSObject 的子类,多继承在这里是用protocol 委托代理来实现的 ,ood的多态特性在obj-c中经过委托来实现。
37.bject-C有私有方法吗?私有变量呢?
objective-c – 类里面的方法只有两种, 静态方法和实例方法.
在类里面声名一个私有方法 @interface Controller : NSObject
{ NSString *something;
} + (void)thisIsAStaticMethod; –(void)thisIsAnInstanceMethod; @end @interface Controller
(private)
-(void)thisIsAPrivateMethod; @end
@private能够用来修饰私有变量 在Objective‐C中,全部实例变量默认都是私有的,全部实例方法默认都是公有的
38. 堆和栈的区别?
管理方式:对于栈来说,是由编译器自动管理,无需咱们手工控制;对于堆来讲,释放工做由程序员控制,容易产生memory leak。
申请大小:栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域
堆:是向高地址扩展的数据结构,是不连续的内存区域。
分配方式:堆都是动态分配的 ,动态分配由alloca函数进行分配
栈的动态分配由编译器进行释放,无需咱们手工实现
39. kvc和kvo的区别?
kvc:键值编码,是一种间接访问对象的属性,使用字符串来标示属性
kvo:键值观察机制,提供了观察某一属性变化的方法
40. 线程和进程的区别?
答:主要不一样的是操做系统资源管理方式
线程是一个进程中不一样的执行路径,线程有本身的堆、局部变量
进程有独立的地址空间,一个线程死掉,整个进程就会死掉
41. #import和#include的区别,@class表明什么?
答:@class通常用于头文件中须要声明该类的某个实例变量的时候用到,在m文件中仍是须要使用#import 而#import比起#include的好处就是不会引发重复包含。
42. 类别的做用?
答:有时咱们须要在一个已经定义好的类中增长一些方法,而不想去重写该类。能够使用类别对该类扩充新的方法。
注意:类别只能扩充方法,而不能扩充成员变量。
代理的做用
委托代理(degegate),目的是改变和传递控制链
顾名思义,把某个对象要作的事情委托给别的对象去作。那么别的对象就是这个对象的代理,代替它来打理要作的事。反映到程序中,首先要明确一个对象的委托方是哪一个对象,委托所作的内容是什么。
委托机制是一种设计模式。
多态:子类的指针能够赋值给父类
43.链表和数组的区别在哪里?
两者都属于一种数据结构
从逻辑结构来看
1. 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的状况。当数据增长时,可能超出原先定义的元素个数;当数据减小时,形成内存浪费;数组能够根据下标直接存取。
2. 链表动态地进行存储分配,能够适应数据动态地增减的状况,且能够方便地插入、删除数据项。(数组中插入、删除数据项时,须要移动其它数据项,很是繁琐)链表必须根据next指针找到下一个元素
从内存存储来看
1. (静态)数组从栈中分配空间, 对于程序员方便快速,可是自由度小
2. 链表从堆中分配空间, 自由度大可是申请管理比较麻烦
从上面的比较能够看出,若是须要快速访问数据,不多或不插入和删除元素,就应该用数组;相反, 若是须要常常插入和删除元素就须要用链表数据结构了。
44. main()
{ int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
答:2,5 *(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5
&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
int *ptr=(int *)(&a+1);则ptr实际是&(a[5]),也就是a+5
缘由以下:&a是数组指针,其类型为 int (*)[5];
而指针加1要根据指针类型加上必定的值,不一样类型的指针+1以后增长的大小不一样。
a是长度为5的int数组指针,因此要加 5*sizeof(int),因此ptr实际是a[5],
可是prt与(&a+1)类型是不同的(这点很重要),因此prt-1只会减去sizeof(int*)
a,&a的地址是同样的,但意思不同
a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址, a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].
45. 写一个委托的interface
@protocol MyDelegate;
@interface MyClass: NSObject
{ id <MyDelegate> delegate; }
//委托方法@protocol MyDelegate- (void)didJobs:(NSArray *)args;
@end
46. 写一个NSString类的实现
+(id)initWithCString:(const char *)nullTerminatedCStringencoding:(NSStringEncoding)encoding;
+ (id)stringWithCString: (const char*)nullTerminatedCString encoding: (NSStringEncoding)encoding
{ NSString *obj;
obj = [selfallocWithZone: NSDefaultMallocZone()];
obj = [objinitWithCString: nullTerminatedCString encoding: encoding];
returnAUTORELEASE(obj);
}
47. 关键字const有什么含意?修饰类呢?static的做用,用于类呢?还有extern c的做用
const意味着"只读",下面的声明都是什么意思?
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前两个的做用是同样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针能够)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是能够修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
结论:·;关键字const的做用是为给读你代码的人传达很是有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。若是 你曾花不少时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(固然,懂得用const的程序员不多会留下的垃圾让别人来清 理的。) ·; 经过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。 ·; 合理地使用关键字const能够使编译器很天然地保护那些不但愿被改变的参数,防止其被无心的代码修改。简而言之,这样能够减小bug的出现。
(1)欲阻止一个变量被改变,能够使用 const 关键字。在定义该 const 变量时,一般须要对它进行初 始化,由于之后就没有机会再去改变它了;(2)对指针来讲,能够指定指针自己为 const,也能够指定指针所指的数据为 const,或两者同时指 定为 const;
(3)在一个函数声明中,const 能够修饰形参,代表它是一个输入参数,在函数内部不能改变其值; (4)对于类的成员函数,若指定其为 const 类型,则代表其是一个常函数,不能修改类的成员变量; (5)对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。
关键字volatile有什么含意?并给出三个不一样的例子。一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都当心地从新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
· ;并行设备的硬件寄存器(如:状态寄存器)
· ; 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
· ; 多线程应用中被几个任务共享的变量
· ;一个参数既能够是const还能够是volatile吗?解释为何。
· ; 一个指针能够是volatile 吗?解释为何。
下面是答案:
· ; 是的。一个例子是只读的状态寄存器。它是volatile由于它可能被意想不到地改变。它是const由于程序不该该试图去修改它。
·; 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
static关键字的做用:
(1)函数体内 static 变量的做用范围为该函数体,不一样于 auto 变量,该变量的内存只被分配一次,所以其值在下次调用时仍维持上次的值; (2)在模块内的 static 全局变量能够被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 它的模块内;
(4)在类中的 static 成员变量属于整个类所拥有,对类的全部对象只有一份拷贝;
(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,于是只能访问类的static 成员变量。
extern "C"的做用:
(1)被 extern "C"限定的函数或变量是 extern 类型的;
extern是 C/C++语言中代表函数和全局变量做用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量能够在本模块或其它模块中使用。
(2)被 extern "C"修饰的变量和函数是按照 C 语言方式编译和链接的;
extern "C"的惯用法
(1)在 C++中引用 C 语言中的函数和变量,在包含 C 语言头文件(假设为 cExample.h)时,需进 行下列处理:
extern "C" { #include "cExample.h" }
而在 C语言的头文件中,对其外部函数只能指定为 extern 类型,C语言中不支持 extern "C"声明, 在.c 文件中包含了 extern "C"时会出现编译语法错误。
(2)在 C 中引用 C++语言中的函数和变量时,C++的头文件需添加 extern "C",可是在 C 语言中不 能直接引用声明了 extern "C"的该头文件,应该仅将 C 文件中将 C++中定义的extern "C"函数声明为 extern 类型。
48.为何标准头文件都有相似如下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif /*...*/
#ifdef __cplusplus
}
#endif
#endif /* __INCvxWorksh */
显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的做用是防止该头文件被重复引用。
49. #import跟#include的区别,@class呢?
@class通常用于头文件中须要声明该类的某个实例变量的时候用到,在m文件中仍是须要使用#import而#import比起#include的好处就是不会引发交叉编译。
50.线程与进程的区别和联系?
答:进程和线程都是由操做系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
程和线程的主要差异在于它们是不一样的操做系统资源管理方式。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。
线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。
51.列举几种进程的同步机制,并比较其优缺点。
答案:原子操做、信号量机制、自旋锁、管程、会合、分布式系统
进程之间通讯的途径
答案:共享存储系统消息传递系统管道:以文件系统为基础
进程死锁的缘由
答案:资源竞争及进程推动顺序非法
死锁的4个必要条件
答案:互斥、请求保持、不可剥夺、环路
死锁的处理
答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁
52.什么是键-值,键路径是什么
答:模型的性质是经过一个简单的键(一般是个字符串)来指定的。视图和控制器经过键来查找相应的属性值。在一个给定的实体中,同一个属性的全部值具备相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。
键路径是一个由用点做分隔符的键组成的字符串,用于指定一个链接在一块儿的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每一个键的值也是相对于其前面的性质。键路径使您能够以独立于模型实现的方式指定相关对象的性质。经过键路径,您能够指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性。
For example, the keypath address.streetwould get the value of the address property from thereceivingobject, and then determine the street property relative to the addressobject.
53.c和obj-c如何混用
1)obj-c的编译器处理后缀为m的文件时,能够识别obj-c和c的代码,处理mm文件能够识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,并且cpp文件include的头文件中,也不能出现obj-c的代码,由于cpp只是cpp
2) 在mm文件中混用cpp直接使用便可,因此obj-c混cpp不是问题
3)在cpp中混用obj-c其实就是使用obj-c编写的模块是咱们想要的。 若是模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中能够使用obj-c的东西,能够import,只是后缀是mm。 若是模块以函数实现,那么头文件要按c的格式声明函数,实现文件中,c++函数内部能够用obj-c,但后缀仍是mm或m。
总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就能够用了,cpp混用obj-c的关键是使用接口,而不能直接使用实现代码,实际上cpp混用的是obj-c编译后的o文件,这个东西实际上是无差异的,因此能够用。obj-c的编译器支持cpp.
54.目标-动做机制
答:目标是动做消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见"插座变量"部分) 的形式保有其动做消息的目标。
动做是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动做而实现的方法。程序须要某些机制来进行事件和指令的翻译。这个机制就是目标-动做机制。
55. cocoa touch框架
这些框架包括:
Core Animation
经过Core Animation,您就能够经过一个基于组合独立图层的简单的编程模型来建立丰富的用户体验。
Core Audio
Core Audio是播放,处理和录制音频的专业技术,可以轻松为您的应用程序添增强大的音频功能。
Core Data提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。
功能列表:框架分类
下面是 Cocoa Touch 中一小部分可用的框架:
音频和视频
CoreAudio
OpenAL
MediaLibrary
AVFoundation
数据管理
Core Data
SQLite
图形和动画
CoreAnimation
OpenGL ES
Quartz 2D
网络/li>
Bonjour
WebKit
BSDSockets
用户应用
AddressBook
CoreLocation
MapKit
StoreKit
56.objc的内存管理
答:若是您经过分配和初始化(好比[[MyClass alloc] init])的方式来建立对象,您就拥有这个对象,须要负责该对象的释放。这个规则在使用NSObject的便利方法new 时也一样适用。
若是您拷贝一个对象,您也拥有拷贝获得的对象,须要负责该对象的释放。若是您保持一个对象,您就部分拥有这个对象,须要在再也不使用时释放该对象。反过来,若是您从其它对象那里接收到一个对象,则您不拥有该对象,也不该该释放它(这个规则有少数的例外,在参考文档中有显式的说明)。
57.自动释放池是什么,如何工做?
答:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,所以自动释放池定义的做用域内的其它对象能够向它发送消息。当程序执行到做用域结束的位置时,自动释放池就会被释放,池中的全部对象也就被释放。
1)ojc-c是经过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,之后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,若是此对象的计数变为了0, 就会被系统销毁.
2) NSAutoreleasePool就是用来作引用计数的管理工做的,这个东西通常不用你管的.
3)autorelease和release没什么区别,只是引用计数减一的时机不一样而已,autorelease会在对象的使用真正结束的时候才作引用计数减一。
58.类工厂方法是什么?
答:类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中,返回被建立的对象,并进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。工厂方法可能不只仅为了方便使用。它们不但能够将分配和初始化合在一块儿,还能够为初始化过程提供对象的分配信息。类工厂方法的另外一个目的是使类(好比NSWorkspace)提供单件实例。虽然init...方法能够确认一 个类在每次程序运行过程只存在一个实例,但它须要首先分配一个“生的”实例,而后还必须释放该实例。工厂方法则能够避免为可能没有用的对象盲目分配内存。
59. 单件实例是什么?
Foundation和Application Kit 框架中的一些类只容许建立单件对象,即这些类在当前进程中的惟一实例。举例来讲,NSFileManager和NSWorkspace 类在使用时都是基于进程进行单件对象的实例化。当向这些类请求实例的时候,它们会向您传递单一实例的一个引用,若是该实例还不存在,则首先进行实例的分配和初始化。单件对象充当控制中心的角色,负责指引或协调类的各类服务。若是类在概念上只有一个实例(好比NSWorkspace),就应该产生一个单件实例,而不是多个实例;若是未来某一天可能有多个实例,您能够使用单件实例机制,而不是工厂方法或函数。
60.动态绑定
—在运行时肯定要调用的方法
动态绑定将调用方法的肯定也推迟到运行时。在编译时,方法的调用并不和代码绑定在一块儿,只有在消实发送出来以后,才肯定被调用的代码。经过动态类型和动态绑定技术,您的代码每次执行均可以获得不一样的结果。运行时因子负责肯定消息的接收者和被调用的方法。运行时的消息分发机制为动态绑定提供支持。当您向一个动态类型肯定了的对象发送消息时,运行环境系统会经过接收者的isa指针定位对象的类,并以此为起点肯定被调用的方法,方法和消息是动态绑定的。并且,您没必要在Objective-C 代码中作任何工做,就能够自动获取动态绑定的好处。您在每次发送消息时,特别是当消息的接收者是动态类型已经肯定的对象时,动态绑定就会例行而透明地发生。
61.obj-c的优缺点objc
优势:
1) Cateogies 2) Posing 3) 动态识别 4) 指标计算 5)弹性讯息传递 6) 不是一个过分复杂的 C 衍生语言 7) Objective-C 与 C++ 可混合编程
缺点:
1) 不支援命名空间 2) 不支持运算符重载 3) 不支持多重继承 4) 使用动态运行时类型,全部的方法都是函数调用,因此不少编译时优化方法都用不到。(如内联函数等),性能低劣。
62.sprintf,strcpy,memcpy使用上有什么要注意的地方?
答:strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, const char *src);将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为'\0',因为拷贝的长度不是由咱们本身控制的,因此这个字符串拷贝很容易出错。
具有字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型为memcpy(char *dst,const char* src, unsigned int len);将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。可是会有内存叠加的问题。
sprintf是格式化函数。将一段数据经过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,形成溢出。