Interview

1.objective-c中的数字对象都有哪些,简述它们与基本数据类型的区别是什么

objective-c 中的数字对象是 NSNumber,可以将 int 封装为 NSNumber 对象,也可以从 NSNumber 中得到 int,(即拆装箱操作):

//将int转为NSNumber
NSNumber *num = [NSNumber numberWithInt:123];
//得到一个int
int testNum = [num intValue]; 
注意区分NSInteger、CGFloat这些都是在Foundation框架下的别名,点进去看实际上它们还是int 和 float

2.用NSLog函数输出一个浮点类型,结果四舍五入,并保留一位小数

NSLog(@"保留两位小数:%.1f",4.8356); 

3.截取字符串”20|http://zcw-java.iteye.com“ 中 ‘|’字符前面及后面的数据,分别输出它们

NSRange range = [str rangeOfString:@"|"];//获取范围
int location = range.location;//获取位置
NSString *str1 = [str subStringToIndex:location];//截取到第几位
NSString *str2 = [str subStringFromIndex:location+1];//从第几位开始截取 

4.objective-c中的字典对象、可变字典对象是哪个,初始化一个含有两个键值对的可变词典对象,并动态的添加和删除一条记录,输出第一条记录

字典NSDictionary,可变字典NSMutableDictionary,
//初始化一个可变词典,带有2个键值对
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2",nil];
//添加
[dic setObject:@"value3" forKey:@"key3"];
//删除
[dic removeObjectForKey:@"key3"];
//获取(按key获取)
[dic objectForKey:@"key1"]; 

5.获取项目根路径,并在其下创建一个名称为userData的目录。

// 获取根路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex: 0];
// 创建文件系统管理器
NSFileManager *fileManager = [[NSFileManager alloc] init];
// 判断userData目录是否存在
if(![fileManager fileExistsAtPath:[NSString stringWithFormat:@"%@/userData", documentsDirectory]]) {
  // 不存在,创建一个userData目录
  [fileManager createDirectoryAtPath:[NSString stringWithFormat:@"%@/userData", documentsDirectory]withIntermediateDirectories:false attributes:nil error:nil];
  //复习文件管理
}
//如果你在mac上测试一定是在你得文稿下边,但装到手机上就不一样了,每一个iPhone应用都会有一个自己独立得documents,所以不会冲突!

6.在一个对象的方法里面:self.name = “object”;和name =”object”有什么不同吗?

这个比较重要,self.name="object"隐式调用了set方法,所以这里如果你的set是自己写的,那么一定不要在set里self.name=name;这样的语法会造成死循环,还会使retainCount(引用计数+1)。 name=“object”,直接赋值!引用计数不变

7. 定义属性时,什么情况使用copy,assign,和retain

  • assign用于基本数据类型,如NSInteger,double,bool。
  • retain 和copy用于对象,copy是深拷贝,而assign是浅拷贝。copy用于当 a指向一个对象,b也想指向同样的对象的时候,如果用assign,a如果释放,再调用b会crash,如果用copy 的方式,a和b各自有自己的内存,就可以解决这个问题。
  • retain 会使计数器加一,也可以解决assign的问题。
  • 另外:tomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。 在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。 
 
 8. ViewController 的viewDidLoad, viewWillAppear, viewDidUnload, dealloc 分别是在什么时候调用,在自定义ViewController的时候这几个函数里面应该做什么工作? 
先来看看 UIViewController 的三个方法:loadView, viewDidLoad 和 viewDidUnload 的关系
(详细参见 loadView, viewDidLoad 和 viewDidUnload 的关系)。
  1)第一次访问UIViewController的view时,view为nil,然后就会调用loadView方法创建view
  2)view创建完毕后会调用viewDidLoad方法进行界面元素的初始化
  2)当内存警告时,系统可能会释放UIViewController的view,将view赋值为nil,并且调用viewDidUnload方法当再次访问UIViewController的view时,view已经在3中被赋值为nil,所以又会调用loadView方法重新创建viewview被重新创建完毕后,还是会调用viewDidLoad方法进行界面元素的初始化
  3)dealloc方法,viewDidUnload和dealloc方法没有关联,当控制器的引用计数为0时,才会调用dealloc方法。
流程应该是这样:

loadView来加载view到内存 -->viewDidLoad函数进一步初始化这些view -->内存不足时,调用viewDidUnload函数释放views -->当需要使用view时有回到第一步
如此循环
  4)viewWillAppear方法,视图即将过渡到屏幕上时调用,(一般在返回需要刷新页面时,我都选择使用代理,所以很少用到)
  5)viewWillDisappear方法,view即将消失时调用。
 
9.简述objective-c内存管理的实现机制,并简述什么时候由你负责释放对象,什么时候不由你释放
 
10.类的定义及声明文件以什么为后缀名?
OC:.m, .h
Swift:.swift
C++:.mm? , .h
 
11.写一个发送同步http请求,并获得返回结果的方法
 
12.怎样启动一个新线程,子线程怎样刷新主UI
 
13.什么是MVC,你工作时怎样运用它
 
14.C语言中讲讲static变量和static函数有什么作用
static关键字有两种意思,你看上下文来判断
1,表示变量是静态存储变量 ,表示变量存放在静态存储区.
2,表示该变量是内部连接 ,(这种情况是指该变量不在任何{}之内,就象全局变量那样,这时候加上static) ,也就是说在其它的.cpp文件中,该变量是不可见的(你不能用).
 
当static加在函数前面的时候,表示该函数是内部连接,之在本文件中有效,别的文件中不能应用该函数.
不加static的函数默认为是全局的,也就是说在其他的.cpp中只要申明一下这个函数,就可以使用它.
 
15、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
    答:全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
    从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
    static函数与普通函数作用域不同。static函数仅在本文件中使用。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
    static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
    static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
    static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
 
16、如何引用一个已经定义过的全局变量?
     答:extern
     可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间 会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
 
16.1 extern "C" 的作用
(1)被 extern "C"限定的函数或变量是 extern 类型的;extern 是 C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。

(2)被 extern "C"修饰的变量和函数是按照 C 语言方式编译和连接的;

 

17. ViewController的didReceiveMemoryWarning怎么被调用:

[supper didReceiveMemoryWarning];

 

18. 什么时候用delegate,什么时候用Notification?

delegate针对one-to-one关系,用于sender接受到reciever的某个功能反馈值。

notification针对one-to-one/many/none,reciver,用于通知多个object某个事件。

 

19. 用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL  

意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数,如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

 

20. 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。

#define MIN(A,B) ((A) <= (B) ? (A) : (B))  

 

21. 写一个委托的 interface

 

22. 写一个NSString类的实现

建立对象需要两个步骤 1分配内存 2初始化

1)分配内存,要sent  alloc  or allocWithZone:  message to the object’s class. 也就是常见的[Class alloc].或是不常见的[Class allocWithZone]
2)初始化.要调用init的方法进行初始化,各种各样的要或不要参数的init方法都算.以上建立对象的方式,返回值要送进 对象自动管理池
+ (id) stringWithCString: (const char*)nullTerminatedCString encoding: (NSStringEncoding)encoding
{
   NSString  *obj;

   obj = [self allocWithZone: NSDefaultMallocZone()];
   obj = [obj initWithCString: nullTerminatedCString encoding: encoding];
   return AUTORELEASE(obj);
}

23. obj-c有多重继承么?不是的话有什么替代方法?

没有,cocoa 中所有的类都是NSObject 的子类。多继承在这里是用protocol 委托代理 来实现的,你不用去考虑繁琐的多继承 ,虚基类的概念。ood的多态特性  在 obj-c 中通过委托来实现.

 

24. obj-c有私有方法么?私有变量呢

没有私有方法,objective-c - 类里面的方法只有两种, 静态方法和实例方法. 这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了. 在类里面声名一个私有方法

//.h
@interface Controller : NSObject {
   NSString *something;  //私有变量
}
+ (void)thisIsAStaticMethod;  //类方法
- (void)thisIsAnInstanceMethod;  //对象方法
@end

//.h
@interface Controller (private)
-(void)thisIsAPrivateMethod; // 私有方法
@end

@private可以用来修饰私有变量

在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的。

 

25.MVC模式的理解,你还熟悉什么设计模式?

1)mvc设计模式 ,模型,视图,控制器,可以将整个应用程序在思想上分成三大块,对应是的数据的存储或处理,前台的显示, 业务逻辑的控制。

2)代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用.比如一个工厂生产了产品,并不想直接卖给用户,而是搞了很多代理商,用户可以直接找代理商买东西,代理商从工厂进货.常见的如QQ的自动回复就属于代理拦截,代理模式在iphone中得到广泛应用.

3)单例模式:说白了就是一个类不通过alloc方式创建对象,而是用一个静态方法返回这个类的对象。系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为,比如想获得[UIApplication sharedApplication];任何地方调用都可以得到 UIApplication的对象,这个对象是全局唯一的。

4)观察者模式: 当一个物体发生变化时,会通知所有观察这个物体的观察者让其做出反应。实现起来无非就是把所有观察者的对象给这个物体,当这个物体的发生改变,就会调用遍历所有观察者的对象调用观察者的方法从而达到通知观察者的目的。

23.http和scoket通信的区别。

http是客户端用http协议进行请求,发送请求时候需要封装http请求头,并绑定请求的数据,服务器一般有web服务器配合(当然也非绝 对)。 http请求方式为客户端主动发起请求,服务器才能给响应,一次请求完毕后则断开连接,以节省资源。服务器不能主动给客户端响应(除非采取http长连接 技术)。iphone主要使用类是NSUrlConnection。

scoket是客户端跟服务器直接使用socket“套接字”进行连接,并没有规定连接后断开,所以客户端和服务器可以保持连接通道,双方 都可以主动发送数据。一般在游戏开发或股票开发这种要求即时性很强并且保持发送数据量比较大的场合使用。主要使用类是CFSocketRef。

 

24.你了解svn,cvs等版本控制工具么?

版本控制 svn,cvs 是两种版控制的器,需要配套相关的svn,cvs服务器。scm是xcode里配置版本控制的地方。版本控制的原理就是a和b同时开发一个项目,a写完当天的代码之后把代码提交给服务器,b要做的时候先从服务器得到最新版本,就可以接着做。 如果a和b都要提交给服务器,并且同时修改了同一个方法,就会产生代码冲突,如果a先提交,那么b提交时,服务器可以提示冲突的代码,b可以清晰的看到,并做出相应的修改或融合后再提交到服务器。

26.什么是push(了解一下)

客户端程序留下后门端口,客户端总是监听针对这个后门的请求,于是 服务器可以主动像这个端口推送消息。

27.什么是沙箱模型?哪些操作是属于私有api范畴,iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么.

某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越。

documents,tmp,app,Library。

  // 取主目录
    NSString *home = NSHomeDirectory();
    NSLog(@"主目录:%@", home);
   
    // 取文档目录
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = documents[0];
    NSLog(@"文档目录:%@", docDir);
   
    NSString *docDir2 = [home stringByAppendingPathComponent:@"Documents"];
    NSLog(@"文档目录2:%@", docDir2);
   
    // 取缓存目录
    NSArray *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);   
    NSString *cacheDir = caches[0];
    NSLog(@"缓存目录:%@", cacheDir);
   
    // 取临时目录
    NSString *tmpDir = NSTemporaryDirectory();
    NSLog(@"临时目录:%@", tmpDir);

  //例如获取程序包中一个图片资源(apple.png)路径的方法:
  NSString *imgPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"png"];
  UIImage *appleImg = [[UIImage alloc] initWithContentsOfFile:imagePath];
//文件IO写入
//1,将数据写到Documents目录:
- (BOOL)writeApplicationData:(NSData *)data toFile:(NSString *)fileName {
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *docDir = [paths objectAtIndex:0];
     if (!docDir) {
        NSLog(@”Documents directory not found!”); return NO;
     }
     NSString *filePath = [docDir stringByAppendingPathComponent:fileName];
     return [data writeToFile:filePath atomically:YES];
}


//2,从Documents目录读取数据:
- (NSData *)applicationDataFromFile:(NSString *)fileName {
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *docDir = [paths objectAtIndex:0];
     NSString *filePath = [docDir stringByAppendingPathComponent:fileName];
     NSData *data = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];
     return data;
}
//NSSearchPathForDirectoriesInDomains这个主要就是返回一个绝对路径用来存放我们需要储存的文件。
- (NSString *)dataFilePath {
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *documentsDirectory = [paths objectAtIndex:0];
     return [documentsDirectory stringByAppendingPathComponent:@"shoppingCar.plist"];
}

NSFileManager* fm=[NSFileManager defaultManager];
if(![fm fileExistsAtPath:[self dataFilePath]]){
  //下面是对该文件进行制定路径的保存
  [fm createDirectoryAtPath:[self dataFilePath] withIntermediateDirectories:YES attributes:nil error:nil];
  //取得一个目录下得所有文件名
  NSArray *files = [fm subpathsAtPath: [self dataFilePath] ];
  //读取某个文件
  NSData *data = [fm contentsAtPath:[self dataFilePath]];
  //或者
  NSData *data = [NSData dataWithContentOfPath:[self dataFilePath]];
}

28.你在开发项目中时,用到了哪些数据存储方式,iphone中常见的方式有哪些,各有什么区别?

数据存储五种形式的应用范围和性能区别

(core data,sqllite,对象序列化,文件直接读写,NSUserDefault(保存数据到temp文件夹中))
文件直接读写 >core data> 对象序列化> sqllite>NSUserDefault.

29.线程的常见方法有哪些,你是如何处理多线程的,多线程同步问题你了解么?

线程创建的几种方式,线程的加锁,休眠,唤醒,解锁,退出,多线程要考虑同步问题,解决同步问题的方式就是对某一资源加锁,当一个线程操作本资源时,其他线程不能操作 。

系统自带线程池(NSOpertionQueue)的作用:

凡是需要启动多个线程的地方都可以使用NSOpertionQueue,加入到NSOpertionQueue中的对象都需要继承NSOpertion。 NSOpertionQueue会在系统内部启动一个独立线程去执行这个被加入对象的main方法。

常用的地方是用NSOprationqueue 下载图片,文件。如果是自己创建一个线程池,无非就是启动多个线程的时候,把这些线程对象放到一个大数组中,如果需要启动线程的时候,先从数组中找空闲线程来使用。自己管理线程池最大的难题是不好处理当启动多个线程后,用户在多个界面的跳转的时候,对线程方法的回调管理。而NSOpertionQueue可以很好的处理他。

30.你连接服务器用的是什么方法,如果请求过程中,网络出了问题这么办?

NSUrlConnection 连接后,有一系列委托方法来接受来自服务器的响应和数据,其中接受相应的方法回得到服务器要传回的数据有多大,接受数据的方法会反复调用来不断接受服务器数据,

如果网络出了问题了,会调用一个方法让你来做相关处理。

31.你使用过json解析方式么,他们的底层是如何处理的你了解么?

底层原理遍历字符串中的字符,最终根据格式规定的特殊字符,比如{}号,[]号, : 号 等进行区分,{}号是一个字典的开始,[]号是一个数组的开始, : 号是字典的键和值的分水岭,最终乃是将json数据转化为字典,字典中值可能是字典,数组,或字符串而已。

37.xml解析的原理是什么,你还用过其他解析方式么?

NSXMLParser, 其他解析方式有自定义二进制解析,就是按字节去解析,电话会谈就是如此,还可以是字符串之间用特殊符号连接的数据,将此数据用特殊符号可以分割成所用数据。

38.协议是什么,有什么作用.?

协议很像java中的接口,某个类实现协议后,就必须实现协议中规定的@require的方法,比如一个类A, 一个类B都实现某“协议”后,这个类A的对象和B的对象都可以赋值给这个协议的类型变量,比如  id<协议> 变量名 = A类或B类的对象,于是这个变量就完成了能够指向多个不同的类的对象并调用对象中的实现协议的方法。

39. 分类有什么作用?

类别的使用 。 类别有三大作用:

1. 可以使本来需要在.h中声明的方法放到.m文件中声明,达到了可以使方法不对外公开。

2. 可以方便的扩展类,甚至系统类都可以轻易扩展,维护了代码原本的结构不受影响。

3. 类别可以写到不同的.h或.m文件中,可以分散代码到跟类别的扩展功能想关联的地方,方便查看。

40.分线程回调主线程方法是什么,有什么作用?

[self  performSelectorOnMainThread:@selector(buttonGo2) withObject:nil waitUntilDone:YES];
[self performSelector:@selector(buttonGo2) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];

需要即时刷新ui控件的时候,经常使用。

41.iphone阅读器,如果要读取一个文本文件,请问你是如何处理编码问题的?另外像pdf格式的文件,你如何读取?

iphone手机阅读器中对于PDF格式的阅读,可以直接用UIWebView控件显示,也可以从网上下到很多直接读取pdf格式的代码直接从pdf中得到数据。

复杂表格动画

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

42.你在开发大型项目的时候,如何进行内存泄露检测的?

可以通过xcode的自带工具run---start with performance tool里有instruments下有个leaks工具,启动此工具后,运行项目,工具里可以显示内存泄露的情况,双击可找到源码位置,可以帮助进行内存泄露的处理。

43.你做iphone开发时候,有哪些传值方式,view和view之间是如何传值的?

44.让一个物体从界面中的一点运动到另外一点,有哪些方法?

四种方式:1. beginAnimation

              2. 线程

              3. NSTimer

              4. 图层动画(路径)

45.你了解哪些加密方式?

Base64, MD5, 循环右移位等.

46.地图定位

CLLocationManager位置管理器  使用Core Location框架来确定iphone的位置(GPS,蜂窝基站三角网,wps三种方式)  MKMapView提供了一套可植入的地图接口,可以让我们在应用中展示地图,并对其进行相关的操作。一般来说,我们可以指定一个展示区域,放一些标记在上面,还可以加盖一些层在上面。MKMapView依赖Google map里面相关服务(如Google Earth API等),所以地图的左下角会有Google字样。

 

47.打开url

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://8004664411"]];mailto://   sms://

48. http网络通信

ASIHTTPRequest 是一个直接在CFNetwork上做的开源项目:提供直接提交(HTTP POST)文件的API,异步请求与队列,自动管理上传与下载队列管理机,ASIFormDataRequest用于适合上传文件,图片数据。

 

49. 图片浏览

UIImagePickerController可以从相册,相机,胶卷里获得图片。

 

50. 对像序列化

NSCoding    encodeWithCoder   initWithCoder

NSKeyedUnarchiver   NSKeyedArchiver

 

51. 各种picker

UIDatePicker   UIPickerView

 

52. 电影播放

     MPMoviePlayerController

     音乐播放

     MPMusicPlayerController

 

53.线程 ?

      a. 线程的创建和使用规则?

         答:NSThread

                 三种方法

                - (id)init; // designated initializer

                - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

                + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

                 - (void)start;

       b. 主分线程

          答:启动分线程,上面已提到!加到主线程方法performSelector!

          //加到主线程addData()是主线程的方法!只有加到主线程后,才能调用主线程的方法

         [target performSelector:@selector(addData:) onThread:[NSThread mainThread] withObject:item waitUntilDone:YES];

           //[target addData:item];//没有加到主线程后,调用主线程的方法!一定会崩!

 

      c.线程锁

         答:NSCondition

                 方法:

                 [thread lock];//加锁

                 sleep(n);//线程休眠

                 [thread singnal];//相当于通知,线程启动

                 [thread unlock];//解锁

                 [thread exit];//线程退出

 

54.各种 排序算法?

     希尔排序、快速排序、冒泡排序、

 

55.通信底层原理

    答:OSI七层模型

    7 应用层:    ftp,smtp,http,telnet,tftp(通过各种协议,最终还是包装成TCP数据包,发送到网络中!)

    6 表现层:

    5 会话层:

    4 传输层:    tcp udp

    3 网络层:    ip,ICMP,IGRP,EIGRP,OSPF,ARP

    2 数据链路层: STP,VT

    1 物理层:

 

56. 为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain的?

答:

      会引起循环引用

      所有的引用计数系统,都存在循环应用的问题。例如下面的引用关系:

          * 对象a创建并引用到了对象b.

          * 对象b创建并引用到了对象c.

          * 对象c创建并引用到了对象b.

 

      这时候b和c的引用计数分别是2和1。

      当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。

      b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。

这种情况,必须打断循环引用,通过其他规则来维护引用关系。我们常见的delegate往往是assign方式的属性而不是retain方式 的属性,

赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。

如果一个UITableViewController 对象a通过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate又是a,

如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。

 

57. 以下每行代码执行后,person对象的retain count分别是多少?

      Person *person = [[Person alloc] init]; count 1

      [person retain]; retain  count 2

      [person release];retain count 1

      [person release];retain count = 0

 

58.在一个对象的方法里面:

      self.name = “object”;

      和

      name =”object”

      有什么不同吗?  

答:self.name = "object"会调用对象的setName()方法,会使object引用计数加1,name = "object"会直接把object赋值给当前对象的name 属性,引用计数不增加。


59.readwrite,readonly,assign,retain,copy,nonatomic属性的作用?

@property是一个属性访问声明,扩号内支持以下几个属性:


1)readwrite: 同时生成 set 和 get 方法

2)readonly: 只生成 get 方法

3)assign: setter方法直接赋值,不进行任何retain操作,可以解决原类型与环循引用问题
。基本数据类型使用 assign,代理一般使用 assign。

4)retain:setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序

5)copy:setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。


6)nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的…)。

7)@synthesize xxx; 来实现实际代码


60.

main()
{
   int a[5]={1,2,3,4,5};
   int *ptr=(int *)(&a+1);
   printf("%d,%d",*(a+1),*(ptr-1));
}

答:2,5

61. obj-c的优缺点

objc优点: 

  1) Cateogies 

  2) Posing 

  3) 动态识别 

  4) 指标计算 

  5)弹性讯息传递 

  6) 不是一个过度复杂的 C 衍生语言 

  7) Objective-C 与 C++ 可混合编程 

缺点: 

  1) 不支援命名空间 

  2)  不支持运算符重载 

  3)不支持多重继承 

  4)使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣

62. 什么是KVC和KVO?

答:1)KVC 是 Key-Value-Coding 的简称,是一种可以直接通过字符串的名字(key)来访问类属性的机制,而不是通过调用的Setter、Getter方法访问。

      2)KVO 是 Key-Value- Observing 的简称,当指定的对象的属性被修改了,允许对象接收到通知的机制。

63.  浅复制和深复制的区别?

答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。深层复制:复制引用对象本身。

25. 类别和类扩展的区别。

 

①分类Category中只能增加方法;

②类扩展Extention不仅可以增加方法,还可以增加实例变量(或者合成属性),只是该实例变量默认是@private类型的(作用范围只能在自身类,而不是子类或其他地方);

③类扩展Extention中声明的方法没被实现,编译器会报警,但是类别中的方法没被实现编译器是不会有任何警告的。这是因为类扩展是在编译阶段被添加到类中,而类别是在运行时添加到类中。

④类扩展Extention不能像分类Category那样拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现。

⑤定义在 .m 文件中的类扩展方法为私有的,定义在 .h 文件(头文件)中的类扩展方法为公有的。类扩展是在 .m 文件中声明私有方法的非常好的方式。

 

26. 代理的作用?

答案:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。另外一点,代理可以理解为java中的回调监听机制的一种类似。

原文地址:https://www.cnblogs.com/actionke/p/4313540.html