1,对象初始化
-(id)init { if(self=[super init])//父类初始化 { //子类成员初始化 } return self; }
以上是常见的对象初始化代码,[super init]是调用父类的初始化函数对父类继承下来的内容进行初始化,然后更新self(
将重新分配后的内存地址赋给self),通常来说调用[super init]之后内存地址是不会发生改变的,但也有例外,比如类簇。
2,关于int, NSInteger, NSNumber 我该用哪个?
首先明确前两个是基本类型,而NSNumber是类。
NSInteger的定义:
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger; #else typedef int NSInteger; typedef unsigned int NSUInteger; #endif
可见不同位数的系统NSInteger会作相应的调整,在32位系统中NSInteger其实就是int,所以一般来说推荐使用NSInteger。
NSNumber是一种类(簇),可以封装int, char, float等基本类型,在一些地方必须使用NSNumber来储存基本类型的变量,比如NSMutableArray,不能存放基本类型的变量,这时候就可以通过把变量封装在NSNumber中再存放到NSMutableArray里。
3,关于@property和@synthesize
相当于用@property关键字声明的变量,会自动创建set和get方法。
看P178的例子:
@interface AllWeatherRadial:Tire { float rainHandling;//可不写,系统会自动添加 float snowHandling;//可不写,系统会自动添加 } @property float rainHandling; @property float snowHandling; @end @implementation @synthesize rainHandling;//可不写,系统会自动添加 @synthesize snowHandling;//可不写,系统会自动添加 @end
带注释的几句都可以不写,系统会自动添加。
有了属性之后,就可以用点表达式来方便地调用set和get方法了。
4,assign, retain, copy属性
在写NSString属性的时候可以声明上面任意一种属性(默认为assign),比如:
@property (copy) NSString* name;
从字面可以看出来assign只是简单地将对象指针指向传进来的内存,当内存在外部被释放,则name会变成野指针;retain会增加内存的计数值防止内存被意外释放,但外部修改内存内容则name的内容也会跟着改变;copy则复制了传进来的内存,外部修改不会影响到这块内存。
5,为什么有时候访问成员变量的时候采用的是“下划线+变量名”的方式?
前面问题3的时候我们说变量声明和@synthesize都可以不写,这时候编译器会自动给我们声明一个带下划线的变量 _var和@synthesize语句。比如当我们声明了@property (copy) NSString*
name;那么系统会添加:
@NSString* _name;
@synthesize name=_name;
那么当我们使用点方法访问name时,会调用set方法进行copy,而当我们直接访问_name时,则不会copy。
self.name=[[NSString alloc]
initwithformat:@"new String"];//会copy
"new String"
_name=
[[NSString alloc]
initwithformat:@"new String"];//不会copy
"new String"