-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path语法.txt
169 lines (115 loc) · 10.9 KB
/
语法.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
属性声明:
@property
使用编译指令@property 加属性类型信息和名称,自动生成getter和setter方法,只读在@property后加“(readonly)”,多个相同声明可写在一行用“,”隔开
可以隐藏是否对变量进行了属性声明,子类中只能通过访问方法来访问,不能直接方法父类的实例变量
可用选项:
指定方法名: getter=getter 方法名//
setter=setter 方法名//显示指定getter和setter方法名
读写属性: readonly //只读
readwrite //读写(默认的)
赋值时选项: (各属性之间有排他性)
assign //单纯赋值(不安全,野指针)
retain //进行保持操作
unsafe_unretained //同assign一样(用于ARC)(不安全,野指针)
strong //同assign一样(用于ARC)
weak //弱引用(用于ARC)
copy //复制对象(为什么这么设计?有什么用?避免修改?形参形式?)
以上说明不严谨,详情看图片,更详细的说明见书《Objective_C编程全解》P133 ***这一整段都要好好看
原子操作: nonatomic 非原子性操作,非线程安全(多线程环境)
缺省情况下是原子的
除使用synthesize生成的访问方法,手动定义的访问方法在不存在多线程竞争时,也可以加上此选项
setter option:指定访问属性用的方法名
例:@property(setter=setValue:) int hitPoint// 使用点运算符调用.hitPoint,但世界杀死那个启动的方法是setValue
对于父类中被定义为readonly类型的属性,子类可以将其变为readwrite
@synthesize
使用编译指令@synthesize 加属性名称 就能自动生成和接口文件中声明的属性一致的访问方法,但是属性声明的情况下不允许这种做法,
接口中不使用@property 进行定义就不能再实现文件中使用@synthesize
可以使用此关键字生存名为A 的访问方法,并将其绑定到实例变量B中
例:synthesize value=runningAverage
当接口文件和实现文件中都没有声明的时候(需要使用@property声明),可以直接在类的实现文件中通过@synthesize生成同名同类型的实例变量(传统运行时系统不能使用此功能)
其有效区间从声明之后开始(可用此特性实现封装的目的)
不可以在子类中使用@synthesize对父类中的实例变量生成访问方法,但可以手动实现对应的访问方法,这是为了防止子类可以轻易访问父类中隐藏的实例变量
使用@property 声明属性之后并不能直接在实现类中使用该属性,需要在实现类中使用@synthesize 声明使用什么实例变量对应指定属性之后,使用实例变量代替属性。
@dynamic
可以使用@dynamic关键字告诉编译器自动合成无效,用户会自己生成属性的getter和setter方法
点操作符:
OC会在编译时把使用点操作符访问属性的过程理解为访问方法的调用,
无论实例变量是否存在,只要访问方法存在,都可以通过点操作符访问属性
//这段基本是废话
只能用于类类型的实例变量,不能对id类型的变量应用(不指定类型,无法判断是否存在属性对应的访问方法)
void类型和C语言中的数组类型的变量也不能应用点操作符,另外,不能用于仅可写的属性,因为属性声明中不能声明只写的属性,除以上几点,都可使用
连用点操作符时,如果连用表达式中有一个是nil,则整个表达式的返回值都是nil
e=obj.depth++;//相当于连续调用了getter和setter方法,e=[obj.depth setDepth:[obj.depth +1]]
obj.depth *=n相当于 [obj setDepth:[obj depth] *n]
类的方法中可以使用self的点操作符调用自己的方法
和构造体的成员混用:
调用:
w=win.minSize.width; 这种写法是允许的,等价:w=[win minSize].with;前面的点操作符是访问结构体中的元素使用的
赋值:
不能使用:w.minSize.width=320.0 这种写法
需要:NSSize sz=win.minSize;
sz.width=320.0;
win.minSize=sz;
虽然可以像&cell.size这样通过取地址符&来对结构体成员取地址,但不能通过取址符对点操作符获得的属性取地址,和不能对函数的返回值取值是一样的
当使用[obj.contents retain]这样的语句时需要注意,实际是给getter方法的返回值发送了消息,未必会给Obj 的实例变量contents发送消息(比如getter方法被绑定到了别的属性上?)
使用点操作符访问对象的实例变量和C语言中使用点操作符访问结构体的成员的意义是不一样的,访问对象的实例变量的正统方法是通过“->”访问,
编译器在碰到点操作符的时候并没有直接访问实例变量而是调用了访问方法
没有参数的方法 ,无论是不是和属性相关,都可以和getter方法一样通过点操作符来调用,但原则上还是应该只对属性声明中定义的属性应用点操作符
在OC中使用点操作符的目的只是访问属性
严格来说,使用依赖于实现的方式来访问实例变量是不允许的,所以应该避免直接访问实例变量(????找例子看),但属性对应的访问方法则一定要直接访问实例变量
无论选择哪种方法都是类内部的实现,对外部都是不可见的。
在初始化方法中使用点操作符访问属性的时候要注意,初始化方法执行的时候这个实例还没完成初始化,属性对相应的访问方法有可能还没生成,所以访问时稍不注意就会带来风险
NSObject:
只有一个实例变量,就算Class类型的变量isa,用于标识实例对象属于那个类对象,子类不可修改isa的值。也不能直接访问isa来查询实例变量到底属于那个类。
而要通过实例方法class来查询。
-(Class) class
返回消息接收者所属的类对象
+(Class) class
返回类对象
虽然可以使用类名作为消息的接收者来调用类方法,但当类对象是其他消息的参数,或者将类对象赋值给变量的时候,需要通过这个类方法来获取类对象
+(id)alloc
生成消息接收类的实例对象,子类不允许重写alloc方法
-(void) dealloc
释放实例对象,作为release的结果调用,除了在子类中重写dealloc的情况之外,不允许直接调用dealloc
+(void)initialize
被用于类的初始化,对类中共同使用的变量进行初始化设定等,这个方法会在类收到第一个消息之前被自动执行,不允许手动调用。
+ (id) new
是alloc和init 的组合,返回的实例对象的所有者就算调用new方法的对象,当这并没有什么优点。
依据类的实现不同,不是每次都会返回一个新对象, 有时候也会返回对象池中预先生成的对象,也可能每次都返回同一个对象
+(NSString *) description
表示消息接收者所属类的内容,通常都是这个类的类名
-(NSString *)description
表示消息接收者的实例对象的内容,通常是类名加id值,子类也可以重定义
OC消息发送机制:《Objective-C编程全解》P146
SEL关键字的意义,包括动态性的实现
程序中的方法名(选择器)在编译后会被一个内部标识符所替代,这个内部标识符所对应的数据类型就是SEL类型
所有的实例变量都存在一个Class类型的isa变量,它就是类对象。
运行时系统内部缓存了一个记录着某个类拥有和什么样的选择器对应的方法,方法被定义在何处等信息,下次收到同样消息时,可直接使用缓存信息即可。
以函数的形式调用方法《OC编程全解》P147
在ARC模式下,初始化的方法返回值没被使用,编译时会发生错误,如果在初始化方法以外对self赋值,会出现编译错误
元类:
相当于类对象的类的对象是存在的,类对象的类叫做元类,实例对象所属的类是class,类对象所属的类是metaclass。此概念来源于Smalltalk,但现在的OC中已经不存在元类的概念了,
程序中也不能操作元类
类对象中保存的是实例方法, 元类对象中保存的是类方法,通过这样的定义能统一实现实例方法和类方法的调用机制。
所有类的类对象都可以执行根类的实例方法,即使在派生类中重新定义了实例方法,根类中的方法也会被执行,如果在派生类中将实例方法作为类方法重新定义了的话,新定义的方法会被执行
《Objective-C 编程全解》P153
目标-动作模式:
Application框架利用这种原理实现了GUI控件对象间的通信P154
动作方法:
Application框架的目标-动作模式在发送消息时使用了 只有一个id类型的参数,没有返回值的形式:-(void) XXX:(id) sender
通常使用方法setTarget:和setAction:来指定目标和动作,在基于引用计数的内存管理方式下,setTarget:不会对参数进行retain操作,使用ARC时,推荐使用弱引用
Cocoa中的GUI控件和其接口都是用OC实现的
outlet:P155
使用ARC进行开发时,要注意避免形成对象之间的引用循环,除了主要对象之间的连接使用强引用之外,其余的对象之间进行连接时都推荐使用弱引用,属性声明时建议加上assign或weak
环境:
Cocoa环境通常指AppKit和Foundation这两个核心框架,有时也包含Core Foundation 或 Core Data 等框架
IOS使用Cocoa Touch作为GUI环境,由Foundation和UIkit框架组合而成的GUI环境称为Cocoa Touch.
框架详细说明P157
条件编译P162
@selecter
@selecter (方法名) 调用不带参方法
@selecter (方法名:) 调用带参方法,此处参数不能自己传,方法定义时参数可以写什么都行,但是,其实参数是调用者的类型,
@selecter的所有权是调用者本身?(最后这句好像是,需要查证)
页面控制:
present 和dismiss配对使用
push和pop配对使用