objective-c系列-動態類型和動態綁定,objective-c綁定
/*
靜態類型:
變數的類型在編譯之時就被確定下來.
動態類型:
對象的類型由對象的記憶體裡的某個結構資料來決定它是什麼類型,
而不是在編譯之時就被確定下來的資料類型。
對象的類型只有在運行時才知道。
oc中的所有對象都有一個共同的基類(根類):NSObject
oc的動態類型特性完全由NSObject這個類來提供。
分析: NSObject類的一個成員變數: Class isa; 實際上是一個結構體指標類型
typedef struct objc_class * Class;
結構體如下:
struct objc_class {
Class isa; ?
Class super_class; 指向父類的結構體
const char *name; 類名
long version; 版本
long info; 資訊
long instance_size; 對象的記憶體大小
struct objc_ivar_list *ivars; 類的成員變數的列表
struct objc_method_list **methodLists; 類的方法列表
struct objc_cache *cache; //緩衝區
struct objc_protocol_list *protocols; //該類遵守的所有協議的列表
} ;
// SEL 資料類型: 就是oc對方法名的一個編碼類別型,可以理解成一個整數
// 如何將一個方法名編碼?
// 答: 用@selector(方法名)就可以產生一個SEL類型的值
//
// Class: 是一個結構體指標類型,
// 所以isa是一個結構體的地址
// 如果要判斷某個對象是否屬於某個類,那麼直接問這個對象的isa變數,是不是存的某個類的結構體的地址?
[person class] ?= [Person class]
isKindOfClass:
isMemberOfClass:
class 類方法
class 對象方法
performSelector:
performSelector: withObject:
還要理解: SEL資料類型 是對方法的一個編碼,不必深糾這個編碼的值
Class資料類型: struct objc_class*
還要掌握幾個函數:
NSClassFromString: 用處: 通過類名得到Class值
NSStringFromClass: 用處: 通過Class值得到類名
*/
Person *person = [[ Person alloc]init];
SEL sel = @selector(sleeping);
if ([Person instancesRespondToSelector:sel]==YES) {
NSLog(@"Person類的對象具有方法 sleeping");
[person sleeping];
}
else
NSLog(@"Person類的對象沒有方法 sleeping");
if([person class] == [Person class])
{
NSLog(@"你是大壞蛋嘛!");
}
// isKindOfClass: 是問某個對象是否是某個類的對象或某個類的子類的對象
if( YES==[person isKindOfClass:NSClassFromString(@"Person")])
{
NSLog(@"person是Person類的對象");
}
Student * stu=[[Student alloc]init];
if (YES ==[stu isKindOfClass:NSClassFromString(@"Person")]) {
NSLog(@"stu這個對象是Person類的對象或Person類的子類的對象");
}
if( YES==[person isMemberOfClass:NSClassFromString(@"Person")])
{
NSLog(@"person這個對象是Person類的對象");
}
if (YES==[stu isMemberOfClass:NSClassFromString(@"Person")]) {
NSLog(@"stu這個對象是Person類的對象");
}
else
{
NSLog(@"stu這個對象不是Person類的對象");
}
// isMemberOfClass方法的內部就是如下:
// if( [self class]==[Person class] )
// return YES;
// return NO;
//
[person performSelector:@selector(sleeping) withObject:nil];
[person performSelector:@selector(printObject:) withObject:@"Message"];
Class cls = NSClassFromString(@"Person");
NSString *classStr = NSStringFromClass([類名 Class]);// 由類名得到字串
NSLog(@"通過Class得到的類名為:%@",NSStringFromClass(cls));