ObjC学习补充


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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值