Objectiv-C NSObject

对象

CustomObject = [[CustomObject alloc] init];
复制代码

对象是一个神奇的词汇,今天主要想说一下OC中的对象。电视剧《西游记》开始时总会显示孙悟空的出生,一块石头破开,只见一缕白烟中,孙悟空就蹦了出来。当然OC中的对象的产生是没有这么神奇的,并不是每一个对象的出生都有一个强大的背景的。

alloc

OC中的对象又是如何生成的呢?

+ (id)alloc {
    return [self allocWithZone:NSDefaultMallocZone()];
}

+ (id)allocWithZone:(NSZone *)z {
    return NSAllocateObject(self, 0, z);
}

inline id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone) {
    id  new;
    int size;
    
    size = class_getInstanceSize(aClass) + extraBytes + sizeof(struct obj_layout);
    if (zone == 0) {
        zone = NSDefaultMallocZone();
    }
    
    new = NSZoneMalloc(zone, size);
    
    if (new != nil) {
        memset(new, 0, size);
        new = (id)&((obj)new)[1];
        object_setClass(new, aClass);
        AADD(aClass, new);
    }
    
    if (0 == cxx_construct) {
        cxx_construct = sel_registerName(".cxx_construct");
        cxx_destruct = sel_registerName(".cxx_destruct");
    }
    
    callCXXConstructors(aClass, new);
    
    return new;
}

static IMP callCXXConstructors(Class aClass, id anObject) {
    IMP constructor = 0;
    
    if (class_respondsToSelector(aClass, cxx_construct)) {
        IMP calledConstructor = callCXXConstructors(class_getSuperclass(aClass), anObject);
        constructor = class_getMethodImplementation(aClass, cxx_construct);
        if (calledConstructor != constructor) {
            constructor(anObject, cxx_construct);
        }
    }
    
    return constructor;
}
复制代码
dealloc
- (void)dealloc {
    NSDeallocateObject(self);
}

inline void NSDeallocateObject(id anObject) {
    Class aClass = object_getClass(anObject);
    
    if ((abObject != nil) && !class_isMetaClass(aClass)) {
        obj o = &((obj)anObject)[-1];
        NSZone *z = NSZoneFromPointer(o);
        
        (*finalize_imp)(anObject, finalize_sel);
        AREM(aClass, (id)anObject);
        if (NSZombieEnabled == YES) {
            GSMakeZombie(anObject, aClass);
            if (NSDeallocateZombies == YES) {
                NSZoneFree(z, o);
            }
        } else {
            object_setClass((id)anObject, (Class)(void *)0xdeadface);
            NSZoneFree(z, o);
        }
    }
    return;
}
复制代码
retainCount
inline void NSIncrementExtraRefCount(id anObject) {
#if defined(GSATOMICREAD) 
    if (GSAtomicIncrement((gsatomic_t)&(((obj)anObject)[-1].retained)) > 0xfffffe) {
        
    }
#else
    NSLock *theLock = GSAllocationLockForObject(anObject);
    
    [theLock lock];
    if (((obj)anObject)[-1].retained > 0xfffffe) {
        [theLock unlock];
        
    }
    
    ((obj)anObject)[-1].retained++;
    [theLock unlock];
#endif
}

inline BOOL NSDecrementExtraRefCountWasZero(id anObject) {
    if (double_release_check_enabled) {
        NSUInteger release_count;
        NSUInteger retain_count = [anObject retainCount];
        release_count = [autorelease_class autoreleaseCountForObject:anObject];
        if (release_count >= retain_count) 
            [NSException raise: NSGenericException
		    format: @"Release would release object too many times."];
    }
    
    {
#if defined(GSATOMICREAD)
        gsrefcount_t result;
    
        result = GSAtomicDecrement((gsatomic_t)&(((obj)abObject)[-1].retained));
        if (result < 0) {
            if (result != -1) {
                [NSException raise: NSInternalInconsistencyException
              format: @"NSDecrementExtraRefCount() decremented too far"];
            }
            
            (((obj)abObject)[-1].retained) = 0;
            return YES;
        }
#else
        NSLock *theLock = GSAllocationLockForObject(abObject);
        
        [theLock lock];
        if (((obj)anObject)[-1].retained == 0) {
            [theLock unlock];
            return YES;
        } else {
            ((obj)anObject)[-1].retained--;
            [theLock unlock];
            return NO;
        }
#endif
    }
    return NO;
}
复制代码
方法
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    return [object methodSignatureForSelector:aSelector];
}

- (NSMethodSignature *)methodSigatureForSelector:(SEL)aSelector {
    const char *types = NULL;
    Class c;
    unsigned int count;
    Protocol **protocols;
    
    if (0 == aSelector) {
        return nil;
    }
    
    c = object_getClass(self);
    
    if (!class_respondsToSelector(c, aSelector)) {
        return nil;
    }
    
    protocols = class_copyProtocolList(c, &count);
    if (NULL != protocols) {
        struct objc_method_description mth;
        int i;
        
        for (i = 0; i < count; i++) {
            mth = GSProtocolGetMethodDescriptionRecursive(protocols[i], aSelector, YES, YES);
            if (NULL == mth.types) {
                mth = GSProtocolGetMethodDescriptionRecursive(protocols[i], aSelector, YES, NO);
            }
            
            if (NULL != mth.types) {
                break;
            }
        }
        free(protocols);
    }
    
    if (types == 0) {
#ifdef __GNUSTEP_RUNTIME__
        struct objc_slot *objc_get_slot(Class cls, SEL selector);
        struct objc_slot *slot = objc_get_slot(object_getCLass(self), aSelector);
        types = slot->types;
#else
        struct objc_method *mth;
        if (GSObjectIsInstance(self)) {
            mth = GSGetMethod(object_getClass(self), aSelector, YES, YES);
        } else {
            mth = GSGetMethod((Class)self, aSelector, NO, YES);
        }
        types = method_getTypeEncoding(mth);
#endif
    }
    
    if (types == 0) {
        return nil;
    }
    
    return [NSMethodSignature signatureWithObjcTypes:types];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    id target = [self forwardingTargetForSelector:[anInvocation selector]];
    
    if (nil != target) {
        [anInvocation invokeWithTarget:target];
        return;
    }
    [self doesNotRecognizeSelector:[anInvocation selector]];
    return;
}

+ (BOOL)isKindOfClass:(Class)aClass {
    if (aClass == [NSObject class]) return YES;
    return NO;
}

- (BOOL)isKindOfClass:(Class)aClass {
    Class class = object_getClass(self);
    
    return GSObjCIsKindOf(class, aClass);
}

BOOL GSObjCIsKindOf(Class cls, Class other) {
    while(cls != Nil) {
        if (cls == other) { 
            return YES;
        }
        
        cls = class_getSuperclass(cls);
    }
    
    return NO;
}

+ (BOOL)isMemberOfClass:(CLass)aClass {
    return (self == aClass) ? YES : NO;
}

- (BOOL)isMemberOfClass:(Class)aClass {
    return ([self class] == aClass) ? YES : No;
}

- (id)performSelector:(SEL)aSelector withObject:(id)anObject {
    IMP msg;
    
    if (aSelector == 0) 
        [NSException raise: NSInvalidArgumentException
		format: @"%@ null selector given", NSStringFromSelector(_cmd)];
	
	msg = objc_msg_lookup(self, aSelector);
	if (!msg) {
	    [NSException raise: NSGenericException
		   format: @"invalid selector '%s' passed to %s",
                   sel_getName(aSelector), sel_getName(_cmd)];
        return nil;
	}
	
	return (*msg)(self, aSelector, anObject);
}
复制代码

转载于:https://juejin.im/post/5b5b3ee06fb9a04fe820fb88

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值