day10---copy,class,选择器

1.copy(自定义对象)

2.类的本质【理解】—》Class类对象

3.选择器 SEL【重点

一 copy
对某个对象发送copy消息的时候,我们的目的是希望能够拷贝出一份一模一样的对象
【Demo】-【1-copy的使用】

什么是深拷贝和浅拷贝?
深拷贝:真正的复制出一份原来的对象,产生了一个新的对象;
浅拷贝:只拷贝了对象的地址,并没有产生新的对象;(retain就属于浅拷贝)

copy和retain的区别:
1.retain和copy都会让对象的引用计数+1,所以都应该对应的必须有一个release或     autorelease;
2.retain是让原对象引用计数器+1,这里只拷贝了对象的地址,并没有产生新对象,认为是“浅     拷贝”;
3.copy拷贝出了一个新对象,让新对象的引用计数器的值为1,认为是“深拷贝”;

copy的运行机制
//希望能拷贝出一个新对象,跟per1所指向的对象的值一样;
//当一个对象指向copy方法的时候,系统内部会自动的调用copyWithZone:这个方法,这是       一个协议方法,该方法返回的对象就是拷贝出来的新对象;
//以后凡是遇到copy一个自定义的对象,或者遇到属性使用copy修饰的自定义对            象,那么先对该对象遵守一个NSCopying协议,并实现协议方法;
#pragma mark - NSCopying协议方法
-(id)copyWithZone:(NSZone *)zone{
 Person *per = [[Person alloc] initWithAge:self.age andWithName:self.name];

    //在这里属于特殊情况,返回对象的时候不需要加入autorelease
    return per;
}

二 类的本质
当程序一运行起来,系统就会默认吧工程中所有的类都加载一份到内存中(这块内存中保存的是 所有的方法列表),我们可以把这块内存认为是类在内存中的对象,称为“类对象”;
类对象都对应一种类型,Class类型;
Class-》所有的类对象都是Class类型;

类的加载和初始化【了解】
+(void)load;

+(void)initialize;
见【Demo】-【2-类的加载和初始化】

@implementation Dog
//当程序启动的时候,就会加载一次项目中所有的类到内存中,加载完毕后就会调用load方法(只会调用一次),先调用父类,再调用子类;
+(void)load{
NSLog(@"Dog ----load 加载到了内存中");

}

//当第一次使用这个类(类对象)的时候,就会调用initialize这个方法,且只调用一次,先调用父类,再调用子类;
+(void)initialize{
NSLog(@"Dog --- initialize 进行初始化!");

}

@end

类对象:一个类在程序中只有一个类对象;
类的对象:程序中可以有无数个类的对象;


如何获得Class类型的类对象;
1)直接向类的对象发送一个class消息,[per1  class];
2)直接向我们的类名发送class消息,[Person class];

见【Demo】-【3-类对象的使用场合】

    //类对象的使用场合【**掌握下面的几个方法**】
    //1.判断一个类是否是另一个类的子类
    BOOL bl1 = [Person isSubclassOfClass:[NSObject class]];
    if (bl1) {
        NSLog(@"是的");
    }else{
        NSLog(@"不是的");
    }
    
    //2.判断一个指针所指向的对象是否是某种类型
    id obj = [[Person alloc] init];
    BOOL bl2 = [obj isMemberOfClass:[Person class]];
    if (bl2) {
        NSLog(@"是的");
    }else{ 
        NSLog(@"不是的");
    }

    
    //3.判断一个指针所指向的对象是否是某种类型或者它的子类【**常用**】
    id str = @"1111222";
    BOOL bl3 = [str isKindOfClass:[NSString class]];
    if (bl3) {
        NSLog(@"是的");
    }else{
        NSLog(@"不是的");
    }

三 选择器【重点
3.1认识选择器
1)选择器是一种数据类型,这个类型写作SEL
2)SEL声明的变量是用来装“成员方法”的,更确切的说,装“消息”,有点类似于“函数 指针”;

    【作用】
        我们可以通过选择器SEL数据类型实现动态的调用对象的成员方法。

    【Demo】-【4-认识选择器】


数组的排序
见【Demo】-【5-数组的排序】

//        char buf[100];

// printf("请输入您想调用的方法名:\n");
// scanf("%s",buf);
//
// //把C字符串转换成OC字符串
// NSString *str = [NSString stringWithUTF8String:buf];

    //把一个字符串反射出对应的选择器类型

// SEL sel = NSSelectorFromString(str); //***********重点

    Person *per = [[Person alloc] init];
    //定义一个SEL类型的变量;
    //该变量里装的是study这个成员方法;

// SEL sel = @selector(study);
//
//
// //通过选择器调用成员方法;
// [per performSelector:sel];
//
//
//
// SEL sel1 = @selector(setAge:);
// //调用带一个参数的方法;
// [per performSelector:sel1 withObject:@10];
// NSLog(@"per = %d",[per.age intValue]);
//
//
//
// [per performSelector:@selector(setName:) withObject:@"小迪迪"];
// NSLog(@"name = %@",per.name);

    //调用带两个参数的   ,最多只能带两个参数;
    //如果有两个以上的参数,可以考虑重新设计这个方法,比如传数组,或者设计另一个类把这些多个参数都封装在类里面,一起作为参数传过去;

// [per performSelector:<#(SEL)#> withObject:<#(id)#> withObject:<#(id)#>];

    //选择器常用的几个方法
    //1.判断一个“类”是否存在某个方法
    Person *per2 = [[Person alloc] init];
    BOOL bl1 = [Person instancesRespondToSelector:@selector(study)];
    if (bl1) {
        NSLog(@"存在该方法");
        [per2 performSelector:@selector(study)];
    }else{
        NSLog(@"不存在该方法");
    }
    
    
    //2. 判断一个对象是否实现了某个方法  【***常用】
    //常用在调用协议方法的时候,为了保证代码的安全性,在调用代理的协议方法之前,最好是先判断该代理对象是否实现了对应的协议方法;
    BOOL bl2 = [per2 respondsToSelector:@selector(playGame)];
    if (bl2) {
        [per2 playGame];
    }else{
        NSLog(@"你没有实现这个方法!");
    }
    
    //3.协议选择器【了解】
    //协议选择器里面装的是协议
    Protocol *p = @protocol(NSCopying);
    //判断一个对象是否遵守了某个协议
    BOOL bl3 = [per2 conformsToProtocol:p];
    if (bl3) {
        if ([per2 respondsToSelector:@selector(copyWithZone:)]) {
            Person *perCopy = [per2 copy];
            [perCopy release];
        }
    }else{
        NSLog(@"这个类不具备拷贝对象的能力");
    }




数组排序
-(id)initWithAge:(int)age andWithName:(NSString *)name{
if ([super init]) {
    self.age = age;
    self.name = name;
}
return self;

}

-(NSComparisonResult)compareAndName:(Student *)otherStudent{

return [self.name compare:otherStudent.name];

}

-(NSComparisonResult)compareAndAge:(Student *)otherStudent{

if (self.age == otherStudent.age) {
    return [self.name compare:otherStudent.name];
}

// return -[self.age compare:otherStudent.age];
//和上面写法一样的效果
return [@(self.age) compare:@(otherStudent.age)];

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容