编程技巧 - 1

1.销毁变量技巧.


学习XMPP的时候学到的一个很优雅的销毁和置nil方法:

- (void)setupStream;//对应着初始化stream
- (void)teardownStream;//对应着销毁stream

- (void)teardownStream//将相关的变量销毁,看见了没,remove   deactivate   dieconnect    = nil
{
[xmppStreamremoveDelegate:self];
[xmppRosterremoveDelegate:self];
[xmppReconnect        deactivate];
[xmppRoster           deactivate];
[xmppvCardTempModule  deactivate];
[xmppvCardAvatarModuledeactivate];
[xmppCapabilities     deactivate];
[xmppStreamdisconnect];
xmppStream =nil;
xmppReconnect =nil;
    xmppRoster =nil;
xmppRosterStorage =nil;
xmppvCardStorage =nil;
    xmppvCardTempModule =nil;
xmppvCardAvatarModule =nil;
xmppCapabilities =nil;
xmppCapabilitiesStorage =nil;
}

- (void)applicationWillTerminate:(UIApplication *)application//应用被关闭的时候也销毁,所以销毁的情况也要注意!
{
    DDLogVerbose(@"%@: %@",THIS_FILE, THIS_METHOD);

    [selfteardownStream];
}

- (void)dealloc//最常见的啦
{
[selfteardownStream];
}

同样的:

- (void)cleanup
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self.containerView removeFromSuperview];
    [[[[UIApplication sharedApplication] delegate] window] makeKeyWindow];
    [self.window removeFromSuperview];
    self.contentViewController = nil;
    self.window = nil;
}

- (void)dealloc
{
    [self cleanup];
}



总结:不用的变量都要销毁,那内存才可以得以轻松,这是个好习惯,而怎么封装和编码得更漂亮,就得看个人的功底啦!




2.颜色的定义.

#define KCColor(r,g,b) [UIColor colorWithHue:r/255.0 saturation:g/255.0 brightness:b/255.0 alpha:1]

#define kStatusTableViewCellBackgroundColor KCColor(251,251,251)


总结:要用的时候直接调,又方便又好看



3.iOS的API也存在嵌套.

sizeToFit的作用就不详说了,查看文档:

- (CGSize)sizeThatFits:(CGSize)size;     // return 'best' size to fit given size. does not actually resize view. Default is return existing view size
- (void)sizeToFit;                       // calls sizeThatFits: with current view bounds and changes bounds size.
注意到 calls sizeThatFits : 这个方法意思是用当前的视图bounds调用方法sizeThatFits去改变bounds的大小,且用当前的视图bounds大小为参数,说明适度的嵌套又好看又方便!


4.字典的取value非常简单

dictionayVariable[keyValue]    就是等于:  [dictionaryVariable objectForKey:keyValue] 

iOS6以后提供的装箱拆箱:

NSNumber:

原始写法:

NSNumber *value1;

value1 = [NSNumber numberWithInt:12345];

value1 = [NSNumber numberWithFloat:123.45f];

value1 = [NSNumber numberWithDouble:123.45];

value1 = [NSNumber numberWithBool:YES];
便捷写法:

NSNumber *value2;

value2 = @12345;

value2 = @123.45f;

value2 = @123.45;

value2 = @YES;

例子:

NSNumber *piOverSixteen1 = [NSNumber numberWithDouble: ( M_PI / 16 )];

NSString *path1 = [NSString stringWithUTF8String: getenv("PATH")];
可以写成:

NSNumber *piOverSixteen2 = @( M_PI / 16 );

NSString *path2= @( getenv("PATH") );


NSArray:

NSArray *array;

array = @[]; //空数组

array = @[ a ]; //一个对象的数组

array = @[ a, b, c ]; //多个对象的数组

//编译器在处理时:

array = @[ a, b, c ];

//编译器生成的代码:

id objects[] = { a, b, c };

NSUInteger count = sizeof(objects)/ sizeof(id);

array = [NSArray arrayWithObjects:objects count:count];

这里小心的是上面这样写的话编译器无法帮你直面地检查是否有nil值的存在而通过编译


NSDictionary:

NSDictionary *dict;

dict = @{}; //空字典

dict = @{@"key1":@"value1" }; //包含一个键值对的字典

dict = @{ @"key1" : @"value1", @"key2" : @"value", @"key3" : @"value3" }; //包含多个键值对的字典

可以很明显地看到区别就是数组用的是[ ],而字典用的是 { }。

上面讲得都是不可变的,那可变的呢,记得深浅复制吧? 由可变到不可变和不可变到可变都是改变指针的复制,所以:

//采用上述写法构建的容器都是不可变的,如果需要生成可变容器,可以传递-mutableCopy消息。例如

NSMutableArray *mutablePlanets = [@[

@"Mercury", @"Venus", @"Earth",

@"Mars", @"Jupiter", @"Saturn",

@"Uranus", @"Neptune"

] mutableCopy];

NSMutableDictionary *dic=[@{ @"key1" : @"value1", @"key2" : @"value", @"key3" : @"value3" } mutableCopy];

生成可变容器, 传递xxx消息 多好的专业名词!



5.工具函数如何封装得漂亮

封装前:冗杂!

    constraint = [NSLayoutConstraint constraintWithItem:newView  
                                              attribute:NSLayoutAttributeLeading  
                                              relatedBy:NSLayoutRelationEqual  
                                                 toItem:self.view  
                                              attribute:NSLayoutAttributeLeading  
                                             multiplier:1.0f  
                                               constant:20];  
    [self.view addConstraint:constraint];  
      
    constraint = [NSLayoutConstraint constraintWithItem:newView  
                                              attribute:NSLayoutAttributeTrailing  
                                              relatedBy:NSLayoutRelationEqual  
                                                 toItem:self.view  
                                              attribute:NSLayoutAttributeTrailing  
                                             multiplier:1.0f  
                                               constant:-20];  
    [self.view addConstraint:constraint];  
      
    constraint = [NSLayoutConstraint constraintWithItem:newView  
                                              attribute:NSLayoutAttributeTop  
                                              relatedBy:NSLayoutRelationEqual  
                                                 toItem:self.view  
                                              attribute:NSLayoutAttributeTop  
                                             multiplier:1.0f  
                                               constant:20];  
    [self.view addConstraint:constraint];  
      
    constraint = [NSLayoutConstraint constraintWithItem:newView  
                                              attribute:NSLayoutAttributeBottom  
                                              relatedBy:NSLayoutRelationEqual  
                                                 toItem:self.view  
                                              attribute:NSLayoutAttributeBottom  
                                             multiplier:1.0f  
                                               constant:-20];  
    [self.view addConstraint:constraint];  

好的封装方式:

- (void)setEdge:(UIView*)superview view:(UIView*)view attr:(NSLayoutAttribute)attr constant:(CGFloat)constant
{
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:attr relatedBy:NSLayoutRelationEqual toItem:superview attribute:attr multiplier:1.0 constant:constant]];
}


还有这样的:

- (NSMutableArray*)portraitConstraints:(UIView*)greenView yellowView:(UIView*)yellowView blueView:(UIView*)blueView
{
    NSMutableArray* constraintArray = [NSMutableArray array];
    
    [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[greenView]-20-[yellowView(==greenView)]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(greenView, yellowView)]];
    
    [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[greenView]-20-[blueView(==greenView)]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(greenView, blueView)]];
    
    [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[yellowView]-20-[blueView(==yellowView)]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(yellowView, blueView)]];
    
    [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[blueView]-20|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(blueView)]];
    
    return constraintArray;
}


好的封装在于:

1.重复的可以用一个来表示:上面的attr

2.约定俗成或者规定的可以直接在函数体里面设置好:上面的的NSLayoutRelationEqual    multiplier: 1.0

3.可以语意化:例如上面的superView在语义上是优先级高的所以先作为变量,即时在API上并不是首个变量

有待补充...



6.适当使用宏

上面提到的有颜色方法的定义宏,还有很多字符串等等的操作都可以定义成宏,并写在一个.h文件中

定义:

/**
 @brief 判断NSString是否为空
 */
#define isStringEmpty(str)  ((str) == nil || [(str) isKindOfClass:[NSNull class]] || [(str) isEqual:@""])

使用:

if (money == 0 && isStringEmpty(serverId) && isStringEmpty(outId) && !dic &&([dic count] == 0) )
{

//do something.
}

比白白写一个 if 判断语句强多了吧!我经常说的要提高代码的质量,就是如此嘛。



7.“时机”的控制

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    NSLog(@"UIViewController will rotate to Orientation: %d", toInterfaceOrientation);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    NSLog(@"did rotated to new Orientation, view Information %@", self.view);
}

will did 这种“时机”性的方法,要细细品味,为什么要如此做



待续:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值