|
29 | 29 |
|
30 | 30 | @interface CYLUser : NSObject<NSCopying> |
31 | 31 |
|
32 | | - @property (nonatomic, copy, readonly) NSString *name; |
33 | | - @property (nonatomic, assign, readonly) NSUInteger age; |
34 | | - @property (nonatomic, assign, readonly) CYLSex sex; |
| 32 | + @property (nonatomic, readonly, copy) NSString *name; |
| 33 | + @property (nonatomic, readonly, assign) NSUInteger age; |
| 34 | + @property (nonatomic, readonly, assign) CYLSex sex; |
35 | 35 |
|
36 | 36 | - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex; |
37 | 37 | + (instancetype)userWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex; |
|
155 | 155 |
|
156 | 156 | @interface CYLUser : NSObject<NSCopying> |
157 | 157 |
|
158 | | - @property (nonatomic, copy, readonly) NSString *name; |
159 | | - @property (nonatomic, assign, readonly) NSUInteger age; |
160 | | - @property (nonatomic, assign, readwrite) CYLSex sex; |
| 158 | + @property (nonatomic, readonly, copy) NSString *name; |
| 159 | + @property (nonatomic, readonly, assign) NSUInteger age; |
| 160 | + @property (nonatomic, readwrite, assign) CYLSex sex; |
161 | 161 |
|
162 | 162 | - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex; |
163 | 163 | - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age; |
|
174 | 174 | 2. 如果基于第一种修改方法:既然该类中已经有一个“初始化方法” (initializer),用于设置“姓名”(Name)、“年龄”(Age)和“性别”(Sex)的初始值: |
175 | 175 | 那么在设计对应@property时就应该尽量使用不可变的对象:其三个属性都应该设为“只读”。用初始化方法设置好属性值之后,就不能再改变了。在本例中,仍需声明属性的“内存管理语义”。于是可以把属性的定义改成这样 |
176 | 176 |
|
177 | | - @property (nonatomic, copy, readonly) NSString *name; |
178 | | - @property (nonatomic, assign, readonly) NSUInter age; |
179 | | - @property (nonatomic, assign, readonly) CYLSex sex; |
| 177 | + @property (nonatomic, readonly, copy) NSString *name; |
| 178 | + @property (nonatomic, readonly, assign) NSUInter age; |
| 179 | + @property (nonatomic, readonly, assign) CYLSex sex; |
180 | 180 | 由于是只读属性,所以编译器不会为其创建对应的“设置方法”,即便如此,我们还是要写上这些属性的语义,以此表明初始化方法在设置这些属性值时所用的方式。要是不写明语义的话,该类的调用者就不知道初始化方法里会拷贝这些属性,他们有可能会在调用初始化方法之前自行拷贝属性值。这种操作多余而且低效。 |
181 | 181 | 2. `initUserModelWithUserName`如果改为`initWithName`会更加简洁,而且足够清晰。 |
182 | 182 | 2. `UserModel`如果改为`User`会更加简洁,而且足够清晰。 |
183 | 183 | 2. `UserSex`如果改为`Sex`会更加简洁,而且足够清晰。 |
| 184 | + 2. 第二个@property中assign和nonatomic调换位置。 |
| 185 | + 推荐按照下面的格式来定义属性 |
| 186 | + |
| 187 | + ```Objective-C |
| 188 | +@property (nonatomic, readwrite, copy) NSString *name; |
| 189 | + ``` |
| 190 | + 属性的参数应该按照下面的顺序排列: 原子性,读写 和 内存管理。 这样做你的属性更容易修改正确,并且更好阅读。这在[《禅与Objective-C编程艺术 >》](https://github.com/oa414/objc-zen-book-cn#属性定义)里有介绍。而且习惯上修改某个属性的修饰符时,一般从属性名从右向左搜索需要修动的修饰符。最可能从最右边开始修改这些属性的修饰符,根据经验这些修饰符被修改的可能性从高到底应为:内存管理 > 读写权限 >原子操作。 |
184 | 191 |
|
185 | 192 | ####***硬伤部分*** |
186 | 193 |
|
|
198 | 205 | 10. |
199 | 206 | `-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;`方法中`(NSString*)name`,应为`(NSString *)name`,少了空格。 |
200 | 207 | 7. doLogIn方法命名不清晰:笔者猜测是login的意思,应该是粗心手误造成的。 |
201 | | - 2. 第二个@property中assign和nonatomic调换位置。 |
202 | 208 |
|
203 | 209 | ###2. 什么情况使用 weak 关键字,相比 assign 有什么不同? |
204 | 210 | 什么情况使用 weak 关键字? |
@@ -322,9 +328,9 @@ atomic属性通常都不会有性能瓶颈。 |
322 | 328 |
|
323 | 329 | @interface CYLUser : NSObject<NSCopying> |
324 | 330 |
|
325 | | - @property (nonatomic, copy, readonly) NSString *name; |
326 | | - @property (nonatomic, assign, readonly) NSUInteger age; |
327 | | - @property (nonatomic, assign, readonly) CYLSex sex; |
| 331 | + @property (nonatomic, readonly, copy) NSString *name; |
| 332 | + @property (nonatomic, readonly, assign) NSUInteger age; |
| 333 | + @property (nonatomic, readonly, assign) CYLSex sex; |
328 | 334 |
|
329 | 335 | - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex; |
330 | 336 | + (instancetype)userWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex; |
@@ -357,9 +363,9 @@ atomic属性通常都不会有性能瓶颈。 |
357 | 363 |
|
358 | 364 | @interface CYLUser : NSObject<NSCopying> |
359 | 365 |
|
360 | | - @property (nonatomic, copy, readonly) NSString *name; |
361 | | - @property (nonatomic, assign, readonly) NSUInteger age; |
362 | | - @property (nonatomic, assign, readonly) CYLSex sex; |
| 366 | + @property (nonatomic, readonly, copy) NSString *name; |
| 367 | + @property (nonatomic, readonly, assign) NSUInteger age; |
| 368 | + @property (nonatomic, readonly, assign) CYLSex sex; |
363 | 369 |
|
364 | 370 | - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex; |
365 | 371 | + (instancetype)userWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex; |
@@ -603,7 +609,7 @@ atomic属性通常都不会有性能瓶颈。 |
603 | 609 |
|
604 | 610 | @implementation Person |
605 | 611 | @synthesize firstName = _myFirstName; |
606 | | - @synthesize lastName = myLastName; |
| 612 | + @synthesize lastName = _myLastName; |
607 | 613 | @end |
608 | 614 |
|
609 | 615 | 我为了搞清属性是怎么实现的,曾经反编译过相关的代码,他大致生成了五个东西 |
|
0 commit comments