ios的代码小tips

三元条件表达式的两元使用

1> 使用格式

表达式A ? 表达式B : 表达式C

2> 运算结果

如果表达式A成立,也就是为“真”,条件运算符的结果就是表达式B的值,否则,就为表达式C的值

3> 三元条件表达式?:是C中唯一一个三目运算符,用来替代简单的if-else语句,同时也是可以两元使用的

!self.completion ?: self.completion(self.userInfo);

等同于

if(self.completion){
    self.completion(self.userInfo);
}

括号中的复合语句

A compound statement enclosed in parentheses 来自gnc的解释
源代码定义:

RETURN_VALUE_RECEIVER = {(
        // your code

       RETURN_VALUE; // 返回值
)};

*下面是一些例子

例子1:
   self.tempBtn = ({
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.frame = CGRectMake(100, 100, 50, 50);
        [button setTitle:@"测试" forState:UIControlStateNormal];
        button;
    });

例子2:
 // 添加myTableView
    _myTableView = ({
        
        UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
        
        tableView.backgroundColor = [UIColor clearColor];
        tableView.dataSource = self;
        tableView.delegate = self;
        tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        [tableView registerClass:[TweetCell class] forCellReuseIdentifier:kCellIdentifier_Tweet];
        [self.view addSubview:tableView]
        tableView;
    });

Note:
1.它最大的意义在于将代码整理分块,将同一个逻辑层级的代码包在一起
2.同时对于一个无需复用小段逻辑,也免去了重量级的调用函数,
3.返回值和代码块结束点必须在结尾

RAC 倒计时

#define kMaxLimitCount 10
    @weakify(self);
    __wea NSInteger number = 0;
    RACSignal *timer = [[[RACSignal interval:1.0f onScheduler:[RACScheduler mainThreadScheduler]] map:^id _Nullable(NSDate * _Nullable value) {
        @strongify(self);
        if (--number <= 0) {
            [self.goBackBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
            return @YES;
        }else{
            [self.goBackBtn setTitle:[NSString stringWithFormat:@"%d秒后可重新获取", (int)number] forState:UIControlStateNormal];
            return @NO;
        }
    }] takeUntilBlock:^BOOL(id  _Nullable x) {
        return number <= 0;
    }];
    
    self.goBackBtn.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        number  = kMaxLimitCount;
        return timer;
    }];

随机数

1.获取一个随机整数范围在:[0,10)包括0,不包括10

int a = arc4random() % 100;

2.获取一个随机数范围在:[10,20],包括10,包括20

int b =10 +  (arc4random() % 10);

转------>生成不重复随机数
思想:其原理就是利用两个数组,第一个数组存放要随机的原始数据,第二个数组存放结果;然后arc4random产生一个随机数,将这个随机数用作下标,把第一个数组对应下标的数据取出并删除。取出后存入第二个数组。然后循环往复就可以了。即便两次arc4random产生的随机数是相同的,但第一个数组对应下标的数据却是不一样的 其实使用NSSet 也可以

两个数组 code

-(NSArray *)randomArray  
{  
    //随机数从这里边产生  
    NSMutableArray *startArray=[[NSMutableArray alloc] initWithObjects:@0,@1,@2,@3,@4,@5,@6,@7, nil nil];  
    //随机数产生结果  
    NSMutableArray *resultArray=[[NSMutableArray alloc] initWithCapacity:0];  
    //随机数个数  
    NSInteger m=8;  
    for (int i=0; i

** NSSet code**

NSArray *array = [[NSArray alloc] initWithObjects:@"A",@"B",@"C",@"D",@"E",nil];  
NSMutableArray *randomArray = [[NSMutableArray alloc] init];  
  
while ([randomArray count] < 3) {  
     int r = arc4random() % [array count];  
     [randomArray addObject:[array objectAtIndex:r]];  
} 

UILabel如何在XIB中换行

在Interface Builder中,选中要换行的UILabel,在属性面板中,选中文本框,输入第一行文字,预要换行时,按住Optional(Alt)+Enter,自动切换到第二行,(如果直接按enter键,则是确定输入的内容,不会自动换行),同时别忘了将Lines属性设置为0

ios的代码小tips_第1张图片
2EE7F56C-672E-45C7-ACA1-AD4147249BF7.png

关于tableView样式为UITableViewStyleGrouped间距的设置

开始的时候,以为这样写就搞定了 如下

        self.tableView.sectionHeaderHeight = 10;
        self.tableView.sectionFooterHeight = 0;

发现发现section=0 的时候高度并没有变化

最后发现self.tableView.sectionHeaderHeight = 10;可以不用设置,直接用代理的方法就可以,但是self.tableView.sectionFooterHeight = 0必须写。 并且如果写了self.tableView.sectionFooterHeight = 0之后,他的代理方法其实是不起作用的。简单来说,就是只需实现下面的代码

self.tableView.sectionFooterHeight = 0;

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 10;
}

上面的例子 是针对多个section的设置,如果只有一个section的话,就比较简单了,直接设置tableHeadView就可以了

self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 10.f)];

或者修改tableView的内边距 contentInset

self.tableView.contentInset = UIEdgeInsetsMake(xxx, 0, 0, 0);

如果是调节section之间的距离,就一起调整两个属性,如果是整体上移,就调节内边距属性contentInset

__weak 和__block的区别

__weak 本身可以解决循环引用,但是出了block作用域之后,就访问不到这个对象了,可以在block里 声明一个__strong 指向这个对象,这样就可以使外部对象既能在 block 内部保持住,又能避免循环引用的问题
__block 本身无法避免循环引用的问题,但是我们可以在 block 内部手动把 blockObj 赋值为 nil 的方式来避免循环引用的问题。另外一点就是 __block 修饰的变量在 block 内外都是唯一的,要注意这个特性可能带来的隐患

protocol里增加property

如果在protocol里定义了属性,有两种方法处理

  1. 就要在实现类里面自己实现get和set方法,Student遵守了协议,可以在Student的实现文件里这样操作
    @synthesize yourProterry=_yourProterry;
  2. 在A的声明文件里,重写这个属性 例如
    in MyProtocal.h
@protocol MyProtocal 
@property (nonatomic, copy) NSString *name;
@end

in Student.h

@interface Student : NSObject
@property (nonatomic, copy) NSString *name;

@end

其实protocol里增加property,主要是为了抽代码,把公共的代码抽出来,对于model而言,有一些共有的属性,可以写在协议里,有需要这些属性的子model 直接遵守改协议即可,比较灵活。

使用webView 提交参数(提交表单时)post方式

     NSURL *url = [NSURL URLWithString: @"你的网址"];
    NSString *body = [NSString stringWithFormat: @"参数1=%@&参数22=%@", @"val1",@"val2"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url];
    [request setHTTPMethod: @"POST"];
    [request setHTTPBody: [body dataUsingEncoding: NSUTF8StringEncoding]];
    [webView loadRequest: request];

tips连接参数时要用&

ARC下的assign和weak区别

The main difference between weak and assign is that the with weak, once the object being pointed to is no longer valid, the pointer is nilled out. Assigning the pointer the value nil avoids many crashes as messages sent to nil are essentially no-ops

Excerpt From: Daniel H Steinberg.

“Developing iOS 7 Apps for iPad and iPhone.” Dim Sum Thinking, Inc, 2014. iBooks. iTunes - Books

weak 比 assign 多了一个功能就是当属性所指向的对象消失的时候(也就是内存引用计数为0)会自动赋值为 nil ,这样再向 weak 修饰的属性发送消息就不会导致野指针操作crash。OC中向nil发消息,程序是不会崩溃的.
tips
在 ARC 模式下编程时,指针变量一定要用 weak 修饰,只有基本数据类型和结构体需要用 assgin ,例如 delegate ,一定要用 weak 修饰
__unsafe_unretained:和__weak一样,唯一的区别便是,对象即使被销毁,指针也不会自动置空, 此时指针指向的是一个无用的野地址。如果使用此指针,程序会抛出 BAD_ACCESS 的异常。

理解__unsafe_unretained

__unsafe_unretained:和__weak 一样,唯一的区别便是,对象即使被销毁,指针也不会自动置空, 此时指针指向的是一个无用的野地址。如果使用此指针,程序会抛出 BAD_ACCESS 的异常
examp1

id __unsafe_unretained obj = [[NSMutableArray alloc]init];  
[obj addObject:@"obj"];  

在第二条语句就会崩溃,分析:
附有__unsafe_unretained修饰符的变量同附有__weak修饰符的变量一样,因为自己生成并持有的对象不能继续为自己持有,所以生成的对象会立即被释放。也就是说在执行完init方法以后,obj指针所指向的内存就已经释放掉了,可是obj指针并没有像附加__weak的指针那样,将指针自动置为nil,它依然指向原来的地址,可是这块地址的内存已经被系统回收了,再访问就是非法的,也就是野指针,再执行后面的addObject方法自然会出错了。
也就是说上面的代码,把__unsafe_unretained换成__weak就不会崩溃,因为obj会自动制置为nil。对nil发送消息是不会有问题的。
examp2

id __unsafe_unretained obj1 = nil;  
{  
    id  obj0 = [[NSMutableArray alloc]init];  
    [obj0 addObject:@"obj"];  
    obj1 = obj0;  
    NSLog(@"obj0 = %@", obj0);  
}  
  
NSLog(@"obj1 = %@", obj1); 

依然在最后的NSLog语句崩溃。分析:
因为__unsafe_unretained既不强引用,也不弱引用,作用域外obj0强引用失效,并且没有其他指针强引用这个对象,所以自动释放持有的对象,obj1就相当于野指针,访问野指针就会崩溃;
也就是说,赋值给附有__unsafe_unretained修饰符变量的对象在通过该变量使用时,如果没有确保其确实存在,那么应用程序就会崩溃;

UIView transitionFromView 实现反复3D旋转效果

效果如下


ios的代码小tips_第2张图片
CMSCoinView.gif
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion

记一下demo链接
文章链接

你可能感兴趣的:(ios的代码小tips)