前言
iOS疑难点总结,部分摘自参考链接
正文
self.var还是_var?
在iOS中常见到如下写法:
@interface Demo ()
@property(nonatomic, strong) NSString *name;
@end
@implementation Demo
- (void)test {
_name = @"";
// self.name = @"";
}
@end
在上述写法中,self.name
和_name
有什么区别呢?
在解释其区别之前,需要先了解一下OC中的属性和实例变量,实例变量具有私有性,一般仅在类内部使用,为了方便给外界读写这个实例变量,就有了属性(@property)
在iOS第一版中,需要同时声明属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求必须声明与之对应的实例变量;如下:
// MyViewController.h
@interface MyViewController : UIViewController
{
UIButton *myButton; // 实例变量
}
@property (nonatomic, retain) UIButton *myButton; // 属性
@end
之后,苹果将默认编译器从GCC转换为LLVM(low level virtual machine),从此不再需要为属性声明实例变量了。如果LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量(即var
属性及与其对应的_var
实例变量),如下:
// MyViewController.h
@interface MyViewController : UIViewController
@property (nonatomic, retain) UIButton *myButton; // 将自动创建一个_myButton实例变量与之对应
@end
在MyViewController.m中可以直接使用_myButton
实例变量,也可以通过self.myButton来访问,二者的区别也是下面要讲解的;
再来看下面一个例子:
// MyViewController.h
@interface MyViewController : UIViewController
{
NSString *name; // 实例变量
}
@end
在MyViewController.m文件中,如果通过self.name访问的话,编译器会报错,Xcode会提示使用->,即使用self->name,这是因为OC中点表达式表示调用方法,而这里的name是一个实例变量,没有与其对应的name方法
另外,还有一个与@property合用的@synthesize,通过@synthesize还可以指定与属性对应的实例变量名,如下:
// MyViewController.h
@interface MyViewController : UIViewController
@property (nonatomic, retain) UIButton * myButton;
@end
// MyViewController.m
@implementation MyViewController
@synthesize myButton = otherButton;
@end
此时,与属性myButton对应的实例变量名为otherButton了,默认的_myButton
就不能使用了;还需要注意的一点是,如果只是声明了@synthesize myButton;
,那么此时默认与myButton对应的实例变量名为myButton,_myButton
也不能用了
到这里我们应该知道了使用self.var
与_var
的区别,即self.var实际上是调用了属性方法,即getter和setter方法,而_var
是直接调用的实例变量,不会走getter和setter方法;因此,这里需要注意的是,当我们要重写getter方法时,在getter方法中必须使用_var
实例变量,否则会造成getter方法的递归调用;同理,重写setter方法时,在setter方法中也只能使用_var
实例变量,否则也会造成settter方法的递归调用;另外,直接访问实例变量的话,就不会调用其setter方法,这样就绕过了为相关属性所定义的内存管理语义。例如:在ARC下直接访问一个语义为copy的属性,那么并不会copy该属性,而仅仅是保留新值并释放旧值
参考链接:
- https://www.jianshu.com/p/48056965ddce
- http://www.cnblogs.com/crazypebble/archive/2013/11/23/3439261.html
@property与@synthesize
我们知道@property可用于在头文件中声明getter和settter方法,@synthesize方法可用于.m文件中实现getter和setter方法;但是实际情况是,如果我们只是在头文件中使用了@property,而没有在.m文件中使用@synthesize,编译器实际上还是会为我们生成getter和setter方法;这是因为从Xcode 4.4 开始,@synthesize属性是默认声明了的
参考链接:
- https://stackoverflow.com/questions/7496463/objective-c-property-declaration-without-implementation-synthesize
扩展(extension)与分类(category)
参考链接:
- https://www.jianshu.com/p/9e827a1708c6
- https://blog.csdn.net/hherima/article/details/44242469
宏定义中的do{}while(0)使用
参考链接:
- https://blog.csdn.net/luoweifu/article/details/38563162
Toolbar,Tab Bar和NavigationBar的区别
Toolbar
和Tab Bar
都是显示在App
的底部,Toolbar
中包含的内容和当前界面相关,比如:添加一个Item
,删除一个Item
,拍照等;Tab Bar
是用于在不同界面之间切换的;需要注意的是,Toolbar
和Tab Bar
不能在同一个界面中使用
NavigationBar
是顶部的导航栏