ObjC学习补充

来源:互联网 发布:mac os 10.12 懒人版 编辑:程序博客网 时间:2024/06/08 05:55


今晚发现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);}@endint 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来获取当前时间。


原创粉丝点击