52Effective总结待续

第二条少用#import,多用@class,向前声明,将引入头文件的时机尽量延后,只有在需要时才引入。可以减少编译时间和防止循环引用。
  .h文件用@class MyView;

# import <UIKit/UIKit.h>
@classMyView;
@interfaceViewController : UIViewController
- (void)sendMyView:(MyView*)mine;
@end

   .m文件用#import"MyView.h",因为需要MyView的方法,否则会报错

#import "ViewController.h"
#import "MyView.h"
@interface ViewController()
@end

@implementation ViewController
- (void)viewDidLoad{
   [super viewDidLoad];
   MyView *myview = [[MyView alloc]init];
   myview.title =@"这是一个view";
   [self sendMyView:myview];
}
- (void)sendMyView:(MyView *)mine
{
}

第三条多用字面量语法,以下两种字符串的初始化方法是等价的,但是第二种会更加简洁,本书建议用第二种方法,我觉得根据实际情况来操作,如果是数组或者是字典的初始化我会选择用第一种方法,因为我不希望程序在遇到异常值的时候奔溃。
  字符串初始化方法

NSString *str = [NSString stringWithFormat:@"abc"];
NSString *str = @"abc";

  类似的初始化方法中还有数组字典等,但是元素不能为nil,否则会奔溃。

NSArray *array = @[@"小明",@"小东",@"小红"];
NSDictionary *dictionary = @{
   @"firstName":@"wu",
   @"lastName":@"qingdao",
   @"age":@10
};
NSString *str = nil;
NSArray *array = @[@"小明",@"小东",str];(会奔溃)
NSArray *array = [NSArray arrayWithObjects:@"小明",@"小东",str,nil];(不会奔溃)

第四条多用类型常量,少用#define

如果只是在本类中使用,那么就在.m文件中定义即可,而且一般以小写字母“k”开头,不管是类型常量还是宏。

  如果用宏定义,那么有可能被替换,比如在一个类中定义kAnimationDuration为0.3,另一个类中定义kAnimationDuration为0.4

#define kAnimationDuration 0.3

  类型常量kAnimationDuration附带类型信息,并且试图修改kAnimationDuration的值的时候会报错   

static const NSTimeIntervalkAnimationDuration = 0.3;

如果打算把这个常量公开,也就是其他类里面也能用到这个常量,那就应该如下定义(extern关键字),请注意“对象常量”(如NSString)和“一般常量”(如NSInterger)写法上的区分。

#import <UIKit/UIKit.h>
extern const NSTimeInterval XJXAnimationDuration;
extern NSString*constXJXMyName;
@interface MyView : UIView
@end

#import "MyView.h"
@implementation MyView
NSTimeInterval const XJXAnimationDuration=0.3;
NSString*const XJXMyName = @"xiao";
@end

第五条 二进制枚举可以减少定义的元素
 //枚举值                                     二进制        十进制

 NOONE    =0 //没人                         00000000        0

 WORKER   =1<<0, //工人                     00000001        1

 DESINGER =1<<1, //设计师                   00000010         2

 MANAGER  =WORKER | DESINGER,//经理         00000011         3

 FINANCIAL =1<<2     //财务                 00000100       4

 BOSS     =FINANCIAL | MANAFGER,//老板      00000111         7

 

 任意两个二进制数,两两按位"或"后得到的数据都是唯一的,比如 WORKER | DESINGER.最后得到的二进制数是00000011。(NOONE除外,因为它与任何数按位"或"后都是,那个数本身)

 所以二进制来表示枚举值的优势是用更少的数据,可以表达更多的状态。所以我们也可以这样定义:

 //枚举值                          二进制     十进制

 NOONE    =0         //没人     00000000    0

 WORKER   =1<<0,     //工人     00000001    1

 DESINGER =1<<1,    //设计师    00000010    2

 FINANCIAL =1<<2     //财务       00000100    4

 

 那如果 return WORKER | DESINGER; 就表示这个人是经理

 如果  return WORKER | DESINGER| FINANCIAL; 就表示这个人是老板。

例子:

#import "ViewController.h"

typedef NS_ENUM(NSUInteger,PostStyle){
  //枚举值            二进制    十进制
  NOONE =0, //没人       00000000    0
  WORKER =1<<0, //工人    00000001    1
  DESINGER =1<<1, //设计师   00000010    2
  FINANCIAL =1<<2 //财务    00000100    4
};

@interfaceViewController (){
  PostStyle style;
}
@end

@implementationViewController
- (PostStyle)Boss
{
  return WORKER | DESINGER| FINANCIAL;
}

- (PostStyle)manager
{
  return WORKER | DESINGER;
}

- (void)viewDidLoad {
   [super viewDidLoad];
   NSLog(@"状态码:老板:%ld,经理:%ld",(unsignedlong)[self Boss],(unsigned long)[selfmanager]);
}

  控制台打印:

**2016-06-1112:55:15.186 52Effective_Objc[1805:434069] ****状态码:老板:****7,****经理:****3****

第七条 对象内部读取数据时,应该通过实例变量(_name)来读取,写入数据用属性来写

懒加载时必须使用实例变量(_name),用self.name会造成死循环
懒加载的优点(其实就是重写 了get方法)

  1不需将对象的实例化写到viewDidLoad,可以简化代码,增强代码的可读性
  
  2对象的实例化在getter方法中,各司其职,降低耦合性
  
  3对系统的内存占用率会减小

#import "XJDropdownMenu.h"
@interface XJDropdownMenu()
@property(nonatomic,weak)UIImageView *containView;
@end
@implementation XJDropdownMenu

  想调用懒加载,就需要用到get方法:self.containView

-(UIImageView *)containView
{
  if (!_containView) { //这里不能用self.containView
     UIImageView *grayBackImageView = [[UIImageView alloc]init];
    _containView = grayBackImageView;
  }
   return _containView;
}

  调用用懒加载

[self.view bringSubviewToFront:self.containView];

第九条 以“类族模式”隐藏实现细节。可以隐藏“抽象基类”的实现细节。
  假如有一个雇员的类(XJEmployee)。它的初始化方法

+ (XJEmployee*)employeeWithType:(EmployeeType)type;

由type来决定返回的类型。一般来说我们会这样写:

typedef NS_ENUM(NSUInteger,EmployeeType){
  Developer,
   Desiginer,
   Finance
};

+ (XJEmployee*)employeeWithType:(EmployeeType)type{
   XJEmployee *employee =[[self alloc]init];
   switch (type) {
     case Desiginer:
      //符合Desiginer的一些属性赋值
     break;
    case Developer:
      //符合Developer的一些属性赋值
     break;
     case Finance:
     //符合Finance的一些属性赋值
   break;
    default:
   break;
  }
    return employee;
}

如果使用族类模式,那么用户无需知道实现细节,这些细节交给XJEmployee的基类去实现。

  声明文件

#import <Foundation/Foundation.h>
typedef NS_ENUM(NSUInteger,EmployeeType){
    Developer,
    Desiginer,
    Finance
};

@interfaceXJEmployee : NSObject
@property(nonatomic,copy)NSString*name;
@property(nonatomic,assign)NSUIntegersalary;

+ (XJEmployee*)employeeWithType:(EmployeeType)type;
- (void)doAdaysWork;
@end

  实现文件

#import "XJEmployee.h"
#import "XJDesigner.h"
#import "XJDeveloper.h"
#import "XJFinance.h"

@implementation XJEmployee

+ (XJEmployee*)employeeWithType:(EmployeeType)type{
   switch (type) {
     case Desiginer:
     return[XJDesigner new];
   break;
     case Developer:
     return[XJDeveloper new];
    break;
     case Finance:
     return[XJFinance new];
    break;
   default:
    break;
}
}

- (void)doAdaysWork{
//子类复写这个方法。
}

  其中的一个子类XJEmployee 声明文件

#import "XJEmployee.h"
@interface XJDeveloper : XJEmployee
@end

  实现文件

#import "XJDeveloper.h"
@implementation XJDeveloper
- (void)doAdaysWork
{
  NSLog(@"XJDeveloper");
}
@end

  另:本书提到UIButton也是使用了族类模式,我验证了一下,发现与书中所说的不符。

UIButton*bun = [UIButton buttonWithType:UIButtonTypeContactAdd];
  NSLog(@"UIButtonTypeContactAdd-->%@",bun);
   if([bun isMemberOfClass:[UIButton class]]){
    NSLog(@"bunisMemberOfClass_UIButton");
   }
   if ([bun isKindOfClass:[UIButton class]]){
    NSLog(@"bunisKindOfClass_UIButton");
   }

//控制台打印数据:

**UIButtonTypeContactAdd--><UIButton:0x7fe710d69e60; frame = (0 0; 22 22); opaque = NO; layer = <CALayer:0x7fe710d6a340>>
**
**2016-06-0615:11:28.526 ****关联对象用法****[2148:188055]bun isMemberOfClass_UIButton
**
**2016-06-06 15:11:28.529 ****关联对象用法****[2148:188055] bun isKindOfClass_UIButton

-isMemberOfClass: 是 NSObject 的方法,用以确定某个 NSObject 对象是否是某个类的成员。与之相似的为 -isKindOfClass:,可以用以确定某个对象是否是某个类或其子类的成员。也就是说bun是UIButton的成员。

  验证一下XJEmployee

XJEmployee*ployee = [XJEmployee employeeWithType:Developer];
NSLog(@"Developer-->%@");
  [XJEmployee employeeWithType:Developer]);
   if ([ployee isKindOfClass:[XJEmployee class]]){
    NSLog(@"ployeeisKindOfClass_XJEmployee");
    }
   if ([ployee isMemberOfClass:[XJEmployee class]]){
   NSLog(@"ployeeisMemberOfClass_XJEmployee");
}

  控制台打印数据:

**2016-06-0615:33:38.171 ****关联对象用法****[2230:195652]Developer--><XJDeveloper: 0x7fd8b250e300>
**
**2016-06-06 15:33:38.172 ****关联对象用法****[2230:195652] ployee isKindOfClass_XJEmployee

只打印了ployeeisKindOfClass_XJEmployee.说明ployee不是XJEmployee的成员,而是XJEmployee子类的成员。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容