今晚发现Objc的学习还有些知识点没学习到,
这里做下补充,后续补充知识点也会在这里更新。
1.谓词NSPredicate :
Cocoa 提供了NSPredicate 用于指定过滤条件,谓词是指在计算机中表示计算真假值的函数,它使用起来有点儿像SQL 的查询条件,主要用于从集合中分拣出符合条件的对象,也可以
用于字符串的正则匹配。
比如按条件匹配过滤两个数组中的元素:
NSArray *arrayFilter = [NSArray arrayWithObjects:@"pict", @"blackrain", @"ip", nil];
NSArray *arrayContents = [NSArray arrayWithObjects:@"I am a picture.", @"I am a guy", @"hl", @"ipad", @"iphone",
@"ippppppppp",nil];
//我想过滤arrayContents的话只要循环 arrayFilter就好了
int i = 0, count = [arrayFilter count];
for(i = 0; i < count; i ++)
{
NSString *arrayItem = (NSString *)[arrayFilter objectAtIndex:i];
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@", arrayItem];
NSLog(@"Filtered array with filter %@, %@", arrayItem, [arrayContents filteredArrayUsingPredicate:filterPredicate]);
}
代码运行将输出:
2013-06-05 01:47:39.788 Test[669:c07] Filtered array with filter pict, (
"I am a picture."
)
2013-06-05 01:47:39.789 Test[669:c07] Filtered array with filter blackrain, (
)
2013-06-05 01:47:39.790 Test[669:c07] Filtered array with filter ip, (
ipad,
iphone,
ippppppppp
)
这里也可以不用循环过滤出来
NSArray *arrayFilter = [NSArray arrayWithObjects:@"abc1", @"abc2", nil];
NSArray *arrayContent = [NSArray arrayWithObjects:@"a1", @"abc1", @"abc4", @"abc2", nil];
NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"NOT (SELF in %@)", arrayFilter];
[arrayContent filterUsingPredicate:thePredicate];//这里arrayContent就是过滤后的结果
我们看到创建谓词使用类方法predicateWithFormat: (NSString*) format,format 里的东西真的
和SQL 的where 条件差不多。另外,参数format 与NSLog 的格式化模版差不多,如果1 和
188.0 是传递过来的参数,你可以写成如下的形式:
@"pid>%d and height<%f",1,188.0
(1.) 逻辑运算符:AND、OR、NOT
这几个运算符计算并、或、非的结果。
(2.) 范围运算符:BETWEEN、IN
例:
@”pid BETWEEN {1,5}”
@"name IN {'Name1','Name2'}"
(3.) 占位符:
NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
@"Name1", @"NAME",nil];
NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];
占位符就是字段对象里的key,因此你可以有多个占位符,只要key 不一样就可以了。
(4.) 快速筛选数组:(这个也叫做燃料过滤器)
前面我们都是使用谓词逐个判断数组内的对象是否符合,其实数组本身有更为便捷的方法,
直接筛选出一个符合谓词的新数组。
NSPredicate *pre = [NSPredicate predicateWithFormat:@"pid>1"];
NSMutableArray *arrayPre=[array filteredArrayUsingPredicate: pre];//结果YES则将值返回新数组
NSLog(@"%@",[[arrayPre objectAtIndex: 0] name]);
(5.) 字符串运算符:
BEGINSWITH、ENDSWITH、CONTAINS 分别表示是否以某字符串开头、结尾、包含。
他们可以与c、d 连用,表示是否忽略大小写、是否忽略重音字母(字母上方有声调标号)。
例:
@”name BEGINSWITH[cd] ‘He’”
判断name 是否以He 开头,并且忽略大小写、忽略重音字母。
(6.) LIKE 运算符:
LIKE 使用?表示一个字符,*表示多个字符,也可以与c、d 连用。
例:
@”name LIKE ‘???er*’” 与Paper Plane 相匹配。
(7.) SELF:
前面的数组中放的都是对象,如果数组放的都是字符串(或者是其他没有属性的类型),该
怎么写谓词呢?这里我们使用SELF。
例:
NSArray *arrays=[NSArray arrayWithObjects: @"Apple", @"Google", @"MircoSoft", nil];
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF=='Apple'"];
(8.) 正则表达式:
NSPredicate 使用MATCHES 匹配正则表达式,正则表达式的写法采用international components
for Unicode (ICU)的正则语法。
例:
NSString *regex = @"^A.+e$";//以A 开头,以e 结尾的字符。
NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
if([pre evaluateWithObject: @"Apple"]){
printf("YES\n");
}else{
printf("NO\n");
}
2.协议-代理delegate设计模式 (委托)
代理设计模式在IPHONE开发中是用得非常多,上午在老大蜻蜓点水般地说了这样一个概念于是花时间来学习下.
@interface Dog:NSObject
{
NSTimer*timer;
int barkCount;
id delegate;//主人
int _ID;
}
-(void) setID:(int)ID;
-(int) ID;
-(void) updateTimer:(id)arg;
-(void) setDelegate :(id)dg;
-(id) Delegate;
@end
@implementation Dog
-(void) setID:(int)ID
{
_ID=ID;
}
-(int) ID
{
return _ID;
}
-(id) init
{
self =[super init];
if(self)
{
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTimer:)userInfo:nil repeats:YES];
//创建一个定时器每隔0.1秒就调用[self updateTimer:nil]这个方法
}
return self ;
}
-(void) updateTimer:(id)arg
{
barkCount++;
NSLog(@"dog bark %d",barkCount);
//通知主人
[delegate bark:self count:barkCount];//调用delegate里面的bark count 方法
}
-(void) setDelegate :(id)dg
{
delegate = dg;
}
-(id) Delegate
{
return delegate;
}
@end
//------
//person
@interface Person:NSObject
{
Dog * _dog;
}
-(void) setDog:(Dog*)dog;
-(Dog*) dog;
@end
@implementation Person
-(void) setDog:(Dog*)dog
{
//_dog=dog;
if(_dog!=dog)
{
[_dog release];
_dog =[dog retain];
//通知主人
[_dog setDelegate:self];
}
}
-(Dog*) dog
{
return _dog;
}
-(void) bark :(Dog *)thisDog count:(int) count
{
//当狗叫的时候来调用
NSLog(@"person this dog %d brak %d",[thisDog ID],count);
}
@end
int main( int argc, const char *argv[] )
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//NSLog(@"1326");
Person *xiaoli= [[Person alloc]init];
Dog *dog =[[Dog alloc] init];
[dog setID:10];
[xiaoli setDog:dog];
while(1)
{
[[NSRunLoop currentRunLoop] run];//让程序不停下.
}
[xiaoli release];
[dog release];
[pool drain];
return 0;
}
程序运行会不断回调dog的updateTimer输出 同时引用delegate中人的方法输出person bark
但主要到是如果按照代码上这样写的话程序会有一个警告,对于有警告强迫症的同学来说,这警告不消灭的话,我心难安啊~
于是可以引用一种比较专业的写法把person中的方法做成一个协议:
@class Dog;
@protocol DogBark<NSObject>
-(void) bark :(Dog *)thisDog count:(int) count;
@end
然后person类实现这个协议,接着在dog类下id deegate定义做下修改,修改成id<DogBark>delegate 属性访问器也对应修改。
-(void) setDelegate :(id<DogBark>)dg;
-(id<DogBark>) Delegate;
运行结果也是一样,于是我们这种比较专业的写法就写好了~
主要核心代码就是定时器中,delegate回调人的方法,这样就是一个比较不错的代理模式。(目前有点晕晕的,还不是很理解= =!)
3.类别Category
Category实际上就是对类的扩展
Category不能完全替代继承,但能做很多继承做不到的事情,写起来麻烦,使用比继承好用。
缺点:只能扩展函数,消息,不能扩展字段,变量等。(这决定Category不能替代继承)
Category的命名:
要扩展类名+扩展变量.[hm]
NSString+ReverseString.h
#import <Foundation/Foundation.h>
@interface NSString (ReverseString)
- (id) reverseString;
@end
NSString+ReverseString.m
#import "NSString+ReverseString.h"
@implementation NSString (ReverseString)
- (id) reverseString
{
NSUInteger len = [self length];
// self 表示字符串本身
NSMutableString *retStr = [NSMutableString stringWithCapacity:len];
while (len > 0) {
unichar c = [self characterAtIndex:--len];
// 从后取一个字符 unicode
NSLog(@" c is %C", c);
NSString *s = [NSString stringWithFormat:
@"%C", c];
[retStr appendString:s];
}
return retStr;
}
@end
实现:
NSString *str=[NSString stringWithString:@"Hello 1326"];
NSLog(@"String:%@",str);
NSString *str2=[str reverseString];
NSLog(@"ReverseString:%@",str2);
结果:
这个知识点之前在Objc学习6 有学过.这里再做一个补充~~
4.Blocks应用
Oc里面非常有意思的语法Blocks,在IOS4.0开始在IPAD、IPHONE上应用很广。比如动画转场,多对象处理,多线程,异步任务,多CPU处理大量用Blocks等。
声明方式:和准C函数指针相似
返回值 变量名 参数 参数值
int (^ BFunc)(int a)
void (^myblocks) (void)=NULL;
myblock = ^(void)
{
NSLog(@"in blocks");
};
NSLog(@"before blocks");
myblock ();
NSLog(@"after blocks");
结果输出:
before blocks
in blocks
after blocks
int (^myblocks2) (int a,int b )=^(int a ,int b)
{
int c =a+b;
return c;
};
NSLog(@"before block2");
int ret =myblock2(10,20);//结果
NSLog(@"after block2 ret %d",ret);
ret运算结果为30
__block int sum =0;
int (^myblocks3) (int a,int b )=^(int a ,int b)
{
sum= a+b;
return 3;
};
myblocks3(20,30);
NSLog(@"sum is %d",sum);
这里用到一个__block关键字是sum强制变为全局变量,这样在myblocks3中就可以访问他了。
运算结果输出:50
-----------------
也可以用typedef 来定义一个typedef
typedef int (^SumBlockT) (int a,int b);
SumBlockT b=^(int a,int b )
{
NSLog(@"c is %d",a+b);
};
b(50,20);
关于blocks的基础的知识就学习到这里,以后要用到再扩展学习吧~
5.NSDate 日期类
NSLog(@"date is %@",[NSDate date]);
NSLog(@"maxdate is %@",[NSDate distantFuture]);
NSLog(@"mindate is %@",[NSDate distantPast]);
结果:
实例2:
NSDateFormatter *df = [[NSDateFormatter alloc]init ];
[df setDateFormat:@"YYYY-MM-dd"];
NSString *d1 =[df stringFromDate:date];
NSLog(@"date is %@",d1);
[df setDateFormat:@"YYYY年MM月dd日"];
NSString *d2 =[df stringFromDate:date];
NSLog(@"%@",d2);
[df release];
也可以用NSCalendar来获取当前时间。