day10---copy,class,選擇器

1.copy(自定義對象)

2.類的本質(zhì)【理解】—》Class類對象

3.選擇器 SEL【重點

一 copy
對某個對象發(fā)送copy消息的時候,我們的目的是希望能夠拷貝出一份一模一樣的對象
【Demo】-【1-copy的使用】

什么是深拷貝和淺拷貝?
深拷貝:真正的復(fù)制出一份原來的對象,產(chǎn)生了一個新的對象;
淺拷貝:只拷貝了對象的地址,并沒有產(chǎn)生新的對象;(retain就屬于淺拷貝)

copy和retain的區(qū)別:
1.retain和copy都會讓對象的引用計數(shù)+1,所以都應(yīng)該對應(yīng)的必須有一個release或     autorelease;
2.retain是讓原對象引用計數(shù)器+1,這里只拷貝了對象的地址,并沒有產(chǎn)生新對象,認為是“淺     拷貝”;
3.copy拷貝出了一個新對象,讓新對象的引用計數(shù)器的值為1,認為是“深拷貝”;

copy的運行機制
//希望能拷貝出一個新對象,跟per1所指向的對象的值一樣;
//當(dāng)一個對象指向copy方法的時候,系統(tǒng)內(nèi)部會自動的調(diào)用copyWithZone:這個方法,這是       一個協(xié)議方法,該方法返回的對象就是拷貝出來的新對象;
//以后凡是遇到copy一個自定義的對象,或者遇到屬性使用copy修飾的自定義對            象,那么先對該對象遵守一個NSCopying協(xié)議,并實現(xiàn)協(xié)議方法;
#pragma mark - NSCopying協(xié)議方法
-(id)copyWithZone:(NSZone *)zone{
 Person *per = [[Person alloc] initWithAge:self.age andWithName:self.name];

    //在這里屬于特殊情況,返回對象的時候不需要加入autorelease
    return per;
}

二 類的本質(zhì)
當(dāng)程序一運行起來,系統(tǒng)就會默認吧工程中所有的類都加載一份到內(nèi)存中(這塊內(nèi)存中保存的是 所有的方法列表),我們可以把這塊內(nèi)存認為是類在內(nèi)存中的對象,稱為“類對象”;
類對象都對應(yīng)一種類型,Class類型;
Class-》所有的類對象都是Class類型;

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

+(void)initialize;
見【Demo】-【2-類的加載和初始化】

@implementation Dog
//當(dāng)程序啟動的時候,就會加載一次項目中所有的類到內(nèi)存中,加載完畢后就會調(diào)用load方法(只會調(diào)用一次),先調(diào)用父類,再調(diào)用子類;
+(void)load{
NSLog(@"Dog ----load 加載到了內(nèi)存中");

}

//當(dāng)?shù)谝淮问褂眠@個類(類對象)的時候,就會調(diào)用initialize這個方法,且只調(diào)用一次,先調(diào)用父類,再調(diào)用子類;
+(void)initialize{
NSLog(@"Dog --- initialize 進行初始化!");

}

@end

類對象:一個類在程序中只有一個類對象;
類的對象:程序中可以有無數(shù)個類的對象;


如何獲得Class類型的類對象;
1)直接向類的對象發(fā)送一個class消息,[per1  class];
2)直接向我們的類名發(fā)送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)選擇器是一種數(shù)據(jù)類型,這個類型寫作SEL
2)SEL聲明的變量是用來裝“成員方法”的,更確切的說,裝“消息”,有點類似于“函數(shù) 指針”;

    【作用】
        我們可以通過選擇器SEL數(shù)據(jù)類型實現(xiàn)動態(tài)的調(diào)用對象的成員方法。

    【Demo】-【4-認識選擇器】


數(shù)組的排序
見【Demo】-【5-數(shù)組的排序】

//        char buf[100];

// printf("請輸入您想調(diào)用的方法名:\n");
// scanf("%s",buf);
//
// //把C字符串轉(zhuǎn)換成OC字符串
// NSString *str = [NSString stringWithUTF8String:buf];

    //把一個字符串反射出對應(yīng)的選擇器類型

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

    Person *per = [[Person alloc] init];
    //定義一個SEL類型的變量;
    //該變量里裝的是study這個成員方法;

// SEL sel = @selector(study);
//
//
// //通過選擇器調(diào)用成員方法;
// [per performSelector:sel];
//
//
//
// SEL sel1 = @selector(setAge:);
// //調(diào)用帶一個參數(shù)的方法;
// [per performSelector:sel1 withObject:@10];
// NSLog(@"per = %d",[per.age intValue]);
//
//
//
// [per performSelector:@selector(setName:) withObject:@"小迪迪"];
// NSLog(@"name = %@",per.name);

    //調(diào)用帶兩個參數(shù)的   ,最多只能帶兩個參數(shù);
    //如果有兩個以上的參數(shù),可以考慮重新設(shè)計這個方法,比如傳數(shù)組,或者設(shè)計另一個類把這些多個參數(shù)都封裝在類里面,一起作為參數(shù)傳過去;

// [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. 判斷一個對象是否實現(xiàn)了某個方法  【***常用】
    //常用在調(diào)用協(xié)議方法的時候,為了保證代碼的安全性,在調(diào)用代理的協(xié)議方法之前,最好是先判斷該代理對象是否實現(xiàn)了對應(yīng)的協(xié)議方法;
    BOOL bl2 = [per2 respondsToSelector:@selector(playGame)];
    if (bl2) {
        [per2 playGame];
    }else{
        NSLog(@"你沒有實現(xiàn)這個方法!");
    }
    
    //3.協(xié)議選擇器【了解】
    //協(xié)議選擇器里面裝的是協(xié)議
    Protocol *p = @protocol(NSCopying);
    //判斷一個對象是否遵守了某個協(xié)議
    BOOL bl3 = [per2 conformsToProtocol:p];
    if (bl3) {
        if ([per2 respondsToSelector:@selector(copyWithZone:)]) {
            Person *perCopy = [per2 copy];
            [perCopy release];
        }
    }else{
        NSLog(@"這個類不具備拷貝對象的能力");
    }




數(shù)組排序
-(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)];

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容