iOS複習筆記15:NSObject
為了描述方便,把如下代碼貼出來:
@interface Student:NSObject-(void)go;-(void)showName:(NSString *)name;-(void)introduce:(NSString *)name :(NSString*)address;@endStudent* stu = [[Student alloc]init];
一 建立和初始化方法
alloc
allocWithZone
new
copy -- 只有不可變到不可變是淺拷貝(相當於retain),其他都是深拷貝,產生不可變的副本(NSString, NSSet等)
mutableCopy -- 深拷貝,產生可變的副本(NSMutablString, NSMutablSet等)
init
重點看copy和mutableCopy
copy:只有不可變到不可變是淺拷貝(相當於retain),其他都是深拷貝,產生不可變的副本(NSString, NSSet等)
mutableCopy:深拷貝,產生可變的副本(NSMutablString, NSMutablSet等)
並不是所有的對象都支援copy,mutableCopy;
遵守NSCopying/NSMutableCopying協議的類可以發送copy/mutableCopy訊息。
這兩個協議裡面分別聲明了下面兩個方法:
- (id)copyWithZone:(NSZone *)zone;- (id)mutableCopyWithZone:(NSZone *)zone;
樣本:
@interface Student:NSObject @end@interface Student(id)copyWithZone:(NSZone *)zone{// 建立的副本對象不需要釋放,有調用者釋放// [self class]防止繼承之後,返回父類對象Student* copy = [[[self class] allocWithZone:zone] init];return copy;}@end
二 記憶體管理方法retain 增加對象的計數器retainCount 返回一個對象當前的計數器release 減少對象的計數器autorelease 自動減少對象的計數器,但是以延遲的方式來實現。dealloc 應用於類來釋放對象執行個體變數並釋放動態記憶體三 判斷方法isKindOfClass:判斷對象是否是某個類或子類的對象isMemberOfClass:判斷對象是否是某個類的對象comfirmsToProtocal:判斷對象是否實現了某個協議instancesRespondToSelector:判斷對象是否實現了某個方法respondsToSelector:判斷類是否實現了某個方法四 間接調用performSelector:performSelector:withObjct:performSelector:withObjct:withObjct:performSelector:withObjct:afterDelay:// 相當於[stu go];[stu performSelector:@selector(go)];// 相當於[stu showName:@"Jun"];[stu performSelector:@selector(showName:) withObjct:@"Jun"];相當於[stu introduce:@"Jun":@"address"];[stu performSelector:@selector(introduce::) withObjct:@"Jun" withObjct:@"address"];// 延時2秒之後調用[stu performSelector:@selector(showName:) withObjct:@"Jun" afterDelay:2];
五 描述
NSObject有一個description方法
+ (NSString *)description;
當我們調用NSLog(@"%@", instance);時,就會調用description方法。
自訂類時,可以重寫這個方法。
六 反射
根據字串反射成類和方法
1 Class反射
// 字串類名到類NSString* className = @"Student";Class class = NSClassFromString(className);Person* p = [[class alloc] init];// 類到字串類名NSString* strClass = NSStringFromClass([Person class]);
2 方法反射
// 字串方法名到方法NSString* funName = @"go";SEL selector = NSSelectorFromString(funName);[stu performSelector:selector];// 方法到字串方法名NSString* strFun = NSStringFromSelector(selector);
七 NSObject本質
@interface NSObject { Class isa;}
可以看到NSObject對象只有一個成員變數Class isa;
Class又是什麼呢?
typedef struct objc_class *Class;
它結構體objc_class指標的別名。
objc_class的定義如下:
struct objc_class { Class isa;};
跟NSObject定義類似,此外還有id也是這樣的。
typedef struct objc_object {
Class isa;
} *id;
所以id就是結構體objc_object指標。
從上面可以看出,NSObject,objc_class,objc_object都僅有一個objc_class * 類型,也就是Class類型的變數isa
以得出結論,類是用objc_class結構體表示的,對象是用objc_object結構體表示的,對象的isa用來標示這個對象是哪個類的執行個體。
看下面的原始碼:
- (BOOL)isMemberOfClass:(Class)cls { return [self class] == cls;}- (Class)class { return object_getClass(self);}Class object_getClass(id obj){ return _object_getClass(obj);}static inline Class _object_getClass(id obj){ if (obj) return obj->isa; else return Nil;}
如果obj不空,返回的Class類型就是obj->isa,否則,返回的是Nil。
這就從源碼上證實了isa就是代表一個對象的類型。