1.Block里的引用类型不做赋值操作,是可以不用在变量前加__block的。
ex:
NSMutableArray *getData = [NSMutableArray array];
__block int i = 0;
dispatch_async(queeDoSth, ^{
//此处不要做=号操作。貌似就不需要强制使用__block;
[getData addObject:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com.cn"] encoding:NSUTF8StringEncoding error:nil]];
//此处若要改变i的值声明的时候必须用__block来修饰。
i = 1;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"i had get www.google.com.cn");
});
});
2.block的使用场合,据说最好不要过多的使用,在需要代码段作为参数,and如上的gcd操作。
ex:
NSLog(@"2*2+4=%d",^(int a){return a*a;}(2)+4);
ps:^(int a){return a*a;}(2)这个就是整体作为一个表达式,来写。
也可以分开来试试写
int(^getDouble)(int) = ^(int a){return a*a;};
NSLog(@"2*2+4=%d",getDouble(2)+4);
这例子就是引出怎么用,具体深层的,要google鸟。这东西的生命期出了{}就结束了(如果里面有什么变量需要留住可能就需要retain下),所以慎用,小道消息说这东西还容易内存溢出。
3.gcd多线程的使用,这东西据说是c的效率高,有人说写法很漂亮(粗人就不发表意见了)。明显的好处避免使用开关锁来付出额外的开销,最主要的是看起来很高端(这个随便说说)。
ex:
1>.同步线程
NSMutableArray *getData = [NSMutableArray array];
//创建一个队列。
dispatch_queue_t queeDoSth = dispatch_queue_create([@"toDoSthBack" UTF8String], NULL);
//添加线程1
dispatch_async(queeDoSth, ^{
[getData addObject:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com.cn"] encoding:NSUTF8StringEncoding error:nil]];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"i had get www.google.com.cn");
});
});
//添加线程2
dispatch_async(queeDoSth, ^{
[getData addObject:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.jike.com"] encoding:NSUTF8StringEncoding error:nil]];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"i had get www.baidu.com");
//因为是同步的,所以写在最后一个。
NSLog(@"getData:%@",getData);
});
});
dispatch_release(queeDoSth);
2>.异步线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
NSLog(@"xx");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"yy");
});
});
//这样叠加。如果需要在线程跑完后干什么,就还得加个group的概念。
dispatch_group_t sysgroup = dispatch_group_create();
dispatch_group_async(sysgroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[getData addObject:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.baidu.com"] encoding:NSUTF8StringEncoding error:nil]];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"i had get www.baidu.com");
});
});
dispatch_group_async(sysgroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[getData addObject:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.jike.com"] encoding:NSUTF8StringEncoding error:nil]];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"i had get www.jike.com");
});
});
dispatch_group_async(sysgroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[getData addObject:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.sina.com"] encoding:NSUTF8StringEncoding error:nil]];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"i had get www.gooojj.com");
});
});
//所有线程完了后干什么事,自己看着办了。
dispatch_group_notify(sysgroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"getData:%@",getData);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"all finshed");
});
});
dispatch_release(sysgroup);
4.谓词,NSPredicate,这东西很神奇,有点sql的味道,可以来验正则,判断范围,和in操作,第一次见就喜欢上了。
ex:
1>.简单的正则匹配。
NSString *regexp = @"^\\d+$";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self matches %@",regexp];
NSLog(@"all number:%@",[predicate evaluateWithObject:@"123"] ?@"Y" :@"N");
2>.还有它的拿手戏,过滤数组。
NSString *regexp = @"^\\d+$";
NSArray *array = [NSArray arrayWithObjects:@"x",@"1123",@"3456",@"yy", nil];
NSLog(@"all number item:%@",[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self matches %@",regexp]]);
3>.对数组里的元素进行过滤
NSArray *array = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:@"x",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"1x",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"777",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"33",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"x",@"1y", nil], nil];
NSLog(@"y is number:%@",[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self.y matches %@",regexp]]);
//换个动词。
NSString *regexp = @"x";
NSArray *array = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:@"x",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"1x",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"777",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"33",@"y", nil],[NSDictionary dictionaryWithObjectsAndKeys:@"x",@"1y", nil], nil];
NSLog(@"the key y is contains x:%@",[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self.y contains %@",regexp]]);
btw:这东西很灵活,用起来也很没有边境,巴实噢。
5.断言,判断表达式是否是YES,如果是就会中断,不能继续往下执行,且只是在debug下才会终止程序运行。
NSAssert(condition,desc),他衍生出很多版本,NSAssert1,NSAssert2,NSAssert3,NSAssert4,NSAssert5后面数字是几就可以多带几个arguments。
NSAssert1(condition,@"wrong:%@",@"xxx");
NSAssert2(condition,@"wrong1:%@,wrong2:%@",@"xxx",@"yyy");
6.调试,断点。这里我只引出下,在debug模式下在console命令模式中的运用,p就是print打印一个值,po就是print object打印一个对象,n就是next往下执行,c就是continue继续执行正在调试的程序。该命令用在程序 由于处理信号或断点而导致停止运行 时。
7.category,对已有class扩展,有点近似js里的原型扩展(prototype)。
ex:
语法就是在类后面加个括号里面描述下扩展的关键字,必须的。
@interface NSString(log)
-(void)stringLog;
@end
@implementation NSString(lossg)
-(void)stringLog{
NSLog(@"log:%@",self);
}
@end
这样所有的nsstring都拥有了这个方法,so
NSString *string = @"ddas";
[string stringLog];
8.1>NSCoding这个协议,就在序列化的时候用。
//archivedDataWithRootObject
-(void)encodeWithCoder:(NSCoder *)aCoder{
//可以通过这个来传值到反序列化的时候用
[aCoder encodeObject:@"xxxx" forKey:@"ssss"];
}
//unarchiveObjectWithData
-(id)initWithCoder:(NSCoder *)aDecoder{
//这个就来取刚才埋下的种子。
self.p = [aDecoder decodeObjectForKey:@"ssss"];
return self;
}
8.2>NSCopying这个协议,在对象copy的时候用([id copy])。
-(id)copyWithZone:(NSZone *)zone;
如果是浅拷贝
-(id)copyWithZone:(NSZone *)zone{
return self;
}
直接这样,他们指向同一个地址。
深拷贝就得改改
-(id)copyWithZone:(NSZone *)zone{
LikeCate *tempObject = [[LikeCate alloc] init];
return tempObject;
}
LikeCate *categ = [[LikeCate alloc] init];
categ.p = @"kkkk";
LikeCate *catef = [categ copy];
catef.p = @"pppsss";
NSLog(@"pp:%@",catef.p);
categ.p = @"ssss";
NSLog(@"ppp:%@",catef.p);
献上栗子一枚。
ps,8.1,8.2如果非原生的对象必须实现对应的协议才能用这些序列化,或者copy。不然得死。
补充点深浅拷贝的细节:
深浅拷贝只针对指针型的变量类型(int,float,bool除外),对于不可变容器(即没有mutable)copy就是浅拷贝,指针指向同一个地址,mutableCopy就是深拷贝,指针指向不同的地址。
PS:copy后的对象不能直接新增,删除元素,而mutableCopy的则可以