OC基礎(chǔ)知識梳理

OC語法相關(guān)

1煮纵、一般什么情況下用分類

  • 用分類可以聲明私有屬性行疏,但是一般情況下不會用分類(category),而是用類擴(kuò)張(extention)
  • 可以用分類拆解體積龐大的類酿联,比如常把AppDelegate 利用分類拆分成推送贞让,分享,登錄等不同功能模塊的分類
  • 可以用于Hook第三方庫的方法续镇,如果你想不修改別人的代碼销部,但是需要修改他們提供的方法,完全可以為需要修改的方法所在類編寫一個分類之后hook酱虎。

2江咳、分類和類擴(kuò)張的區(qū)別

  • extension相當(dāng)于一個頭文件而已,extension(類擴(kuò)張)只能編寫方法聲明爹土,所編寫的方法和屬性都需要在.m文件實現(xiàn)踩身。如果你在extension中書寫了屬性(property)胀茵,那么必需要把extension文件import到.m文件中挟阻,讓系統(tǒng)幫你生成setter和getter方法附鸽,或者導(dǎo)入之后自己手動生成setter方法和getter方法。
  • 分類(category)有自己的數(shù)據(jù)結(jié)構(gòu)objc_category熄浓,可以編寫方法和關(guān)聯(lián)屬性省撑。分類編寫的方法會在runtime的時候俯在,調(diào)用remethodizeClass 把方法整合到類對象中娃惯。
  • 如果類A有兩個分類并且有同名的分類方法趾浅,那么后編譯的分類的方法會插入到類對象方法列表的前面。之后如果調(diào)用該方法揪荣,會出發(fā)msg_Send方法查找往史,后編譯的分類同名方法會被優(yōu)先查找到佛舱。所以會產(chǎn)生類似后編譯分類的同名方法覆蓋其他分類的同名方法現(xiàn)象请祖。
  • 分類的+load方法會在類的+load方法后調(diào)用。分類的+load方法調(diào)用順序和編譯順序有關(guān)
  • 父類的+load方法調(diào)用之后再調(diào)用子類的+load方法刷晋,父類和子類的+load方法調(diào)用完之后再調(diào)用分類的+load方法(調(diào)用順序只和編譯順序有關(guān))
  • initialize方法會在類第一次接受到消息的時候調(diào)用慎陵,調(diào)用順序是父類->子類。如果分類有重寫initialize方法捏悬,則會覆蓋父類的initialize润梯。如果多個分類重寫了initialize方法纺铭,那么就會調(diào)用最后編譯分類的initialize方法。
  • 利用關(guān)聯(lián)對象實現(xiàn)的setter和getter方法扫倡,可以被KVO顿痪。
繼承關(guān)系 BeautyCat -> Cat - > Animal()
類和分類 Animal油够,Animal+bb石咬,Animal+aa卖哎,Cat,Cat+bb焕窝,Cat+aa维贺,BeautyCat溯泣,BeautyCat+aa
測試結(jié)果:
/*------------------------------------------------------*
2021-04-15 11:17:46.141459+0800 cccExtention[40555:7540175] +[Animal load]
2021-04-15 11:17:46.159957+0800 cccExtention[40555:7540175] +[Cat load]
2021-04-15 11:17:46.161076+0800 cccExtention[40555:7540175] +[BeautyCat load]
2021-04-15 11:17:46.161541+0800 cccExtention[40555:7540175] +[BeautyCat(aa) load]
2021-04-15 11:17:46.163238+0800 cccExtention[40555:7540175] +[Animal(aa) load]
2021-04-15 11:17:46.163901+0800 cccExtention[40555:7540175] +[Animal(bb) load]
2021-04-15 11:17:46.164747+0800 cccExtention[40555:7540175] +[Cat(aa) load]
2021-04-15 11:17:46.166138+0800 cccExtention[40555:7540175] +[Cat(bb) load]
2021-04-15 11:17:46.252135+0800 cccExtention[40555:7540175] +[Animal(bb) initialize]
2021-04-15 11:17:46.252318+0800 cccExtention[40555:7540175] +[Cat(bb) initialize]
2021-04-15 11:17:46.253647+0800 cccExtention[40555:7540175] +[BeautyCat(aa) initialize]

疑問

  • category分類的屬性是存儲在管理對象上的垃沦,那么為什么在attachCategories方法中還需要把property_list_t整合到類中呢?
  • 在obj4-781 版本中靶剑,attachCategories方法對一個類的分類數(shù)量做了限制(64個)池充,如果多出64個會怎么處理?
  • xcode 14 如何編譯運(yùn)行obj4-818.2?

3阐污、關(guān)聯(lián)對象

  • 系統(tǒng)維護(hù)了一個全局 AssociationsManager專門用于管理所有關(guān)聯(lián)對象
  • 通過類指針(利用哈希查找)可以快速在AssociationsManager中的AssociationHashMap找到該類的關(guān)聯(lián)對象存儲結(jié)構(gòu)ObjectAssociationMap咱圆。
  • ObjectAssociationMap 的key就是我們調(diào)用objc_setAssociatedObject 設(shè)置的key序苏,value 是一個ObjcAssociation 對象
  • ObjcAssociation對象包含關(guān)聯(lián)屬性的值和內(nèi)存管理方案
  • 可以通過把objc_setAssociatedObject方法的參數(shù)value設(shè)置為nil,刪除某個關(guān)聯(lián)對象值.

ObjcAssociation對象 在runtime源碼的定義

class ObjcAssociation {
    uintptr_t _policy; // 內(nèi)存管理策略()
    id _value; // 存儲的值
};

policy 可以取的值

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};

示例代碼

-(void)setVersion:(NSString * _Nonnull)version
{
    objc_setAssociatedObject(self, @selector(version), version, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

-(NSString *)version
{
    NSString *ver = objc_getAssociatedObject(self, _cmd);
    return ver;
}

4、KVO

  • KVO 是key-value observing的縮寫。
  • KVO是 objective-c 對觀察者模式的實現(xiàn)桶错。
  • 如果一個實例對象ABC添加了KVO胀蛮,那么系統(tǒng)在運(yùn)行時會為這個對象生成一個中間類——NSKVONotifying_ABC粪狼,之后把實例對象ABC的isa指針指向NSKVONotifying_ABC,NSKVONotifying_ABC的superClass指針指向原本類對象狡刘。所以當(dāng)調(diào)用set方法的時候困鸥,會先調(diào)用NSKVONotifying_ABC的set方法。在NSKVONotifying_ABC 的set方法中會調(diào)用willChangeValueForKey 和didChangeValueForKey兩個方法购城。具體實現(xiàn)如下
-(void)setName:(NSString *)name
{
    [self willChangeValueForKey:@"name"];
    [super setName:name]; //原來的setter方法
    [self didChangeValueForKey:@"name"]; // 調(diào)用observeValueForKeyPath 方法
}

示例代碼

//添加監(jiān)測網(wǎng)頁加載進(jìn)度的觀察者
[self.webView addObserver:self
               forKeyPath:NSStringFromSelector(@selector(estimatedProgress))
                  options:0
                  context:nil];
         
-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                      context:(void *)context{
    
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))]
        && object == _webView) {
        NSLog(@"網(wǎng)頁加載進(jìn)度 = %f",_webView.estimatedProgress);
        }
}

5、KVC

流程圖

  • +(BOOL)accessInstanceVariablesDirectly 返回YES漆诽,告訴系統(tǒng)尋找相似的key锣枝,返回NO告訴系統(tǒng)不找相應(yīng)的key,默認(rèn)返回YES,valueForKey方法和setValueForKey方法當(dāng)沒找到key都會導(dǎo)致崩潰
KVC.jpeg

6供鸠、isa走位圖

isa走位圖.png

7楞捂、 屬性關(guān)鍵字有哪些趋厉?可以分為幾類?

  • 屬性關(guān)鍵大體上可以分為三類——讀寫相關(guān)繁堡,引用計數(shù)器相關(guān),原子性操作相關(guān)闻牡。

讀寫相關(guān)

  • readonly绳矩,表示這個屬性在外部緊緊可讀
  • readwrite埋酬,表示這個屬性在外部可讀可寫
  • 如果你要申明一個屬性對外部可讀,對內(nèi)部可讀可寫拳球,那么可以在.h文件用readonly珍特,之后再.m文件再用readwrite

引用計數(shù)器內(nèi)存管理相關(guān)

  • copy屬性關(guān)鍵字常用于修飾不可變對象,比如NSString對象和NSArray對象莱找。不可以對象的copy操作屬于淺拷貝嗜桌,所以不可變對象用strong修飾也是沒問題的骨宠。So,用retain也一樣桦卒。
  • retain 強(qiáng)引用持有對象匿又,在ARC環(huán)境下,用strong取代retain裕偿。
  • strong 強(qiáng)引用持有對象痛单,會讓對象的引用計數(shù)器+1
  • weak 弱引用桦他,不會導(dǎo)致對象的引用計數(shù)器增加谆棱,并且對象釋放的時候圆仔,會把指針置為nil坪郭。
  • assign 一般來說,用于修飾基本數(shù)據(jù)結(jié)構(gòu)嗦锐,在MRC環(huán)境下也可以用于修飾對象沪曙,但是不會導(dǎo)致對象的引用計數(shù)器增加,所以類似 unsafe_unretain碳默,是不安全的缘眶。
  • unsafe_unretain MRC環(huán)境下的屬性關(guān)鍵字巷懈,引用對象,但是不會導(dǎo)致對象引用的計算器+1凑保,也就是普通的指針(對比C++的智能指針)割岛。

線程安全相關(guān)

  • nonatomic犯助,非原子操作剂买,默認(rèn)也是這個屬性。所以默認(rèn)情況下婚肆,屬性讀寫是沒有線程安全的坐慰。
  • atomic,原子操作赞咙,被這個關(guān)鍵字修飾的屬性攀操,讀寫是線程安全。但是歹垫,如何是容器類對象颠放,那么修改容器類對象的內(nèi)容依然是線程不安全的,所以最好還是自己加鎖實現(xiàn)線程安全代碼若贮,而不是用atomic谴麦。

8伸头、objc源碼常見的數(shù)據(jù)結(jié)構(gòu)

isa_t

isa_t 是一個聯(lián)合體,部分源碼如下

union isa_t 
{
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;

#if SUPPORT_PACKED_ISA
# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
    struct {
        uintptr_t nonpointer        : 1;
        uintptr_t has_assoc         : 1;
        uintptr_t has_cxx_dtor      : 1;
        uintptr_t shiftcls          : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
        uintptr_t magic             : 6;
        uintptr_t weakly_referenced : 1;
        uintptr_t deallocating      : 1;
        uintptr_t has_sidetable_rc  : 1;
        uintptr_t extra_rc          : 19;
#       define RC_ONE   (1ULL<<45)
#       define RC_HALF  (1ULL<<18)
    };

    };

可以看出isa_t 只有兩個數(shù)據(jù)成員面哼,一個是指針類型Class cls魔策,一個是unsigned long類型uintptr_t bits河胎,所以整個聯(lián)合體的內(nèi)存只有64位游岳。

  • nonpointer 表示是否對isa開啟指針優(yōu)化 。0代表是純isa指針喷户,1代表除了地址外访锻,還包含了類的一些信息闹获、對象的引用計數(shù)等昌罩。
  • has_assoc 表示是否存在關(guān)聯(lián)對象灾馒。
  • has_cxx_dtor:該對象是否有C++或Objc的析構(gòu)器睬罗,如果有析構(gòu)函數(shù),則需要做一些析構(gòu)的邏輯處理古涧,如果沒有花盐,則可以更快的釋放對象。
  • shiftcls 存在類指針的值柒昏,開啟指針優(yōu)化的情況下职祷,arm64位中有33位來存儲類的指針
  • magic:判斷當(dāng)前對象是真的對象還是一段沒有初始化的空間(有待研究)
  • weakly_referenced:是否被指向或者曾經(jīng)指向一個ARC的弱變量届囚,沒有弱引用的對象釋放的更快
  • deallocating:是否正在釋放
  • has_sidetable_rc:當(dāng)對象引用計數(shù)大于10時意系,則需要進(jìn)位
  • extra_rc:表示該對象的引用計數(shù)值,實際上是引用計數(shù)減一痰催。例如:如果引用計數(shù)為10作郭,那么extra_rc為9弦疮。如果引用計數(shù)大于10胁塞,則需要使用has_sidetable_rc

objc_object 結(jié)構(gòu)體

struct objc_object {
private:
    isa_t isa;
public:
    .....
}

可以看到objc_object在源碼中只有一個私有成員變量isa压语,類型是isa_t胎食,這個結(jié)構(gòu)類型是一個聯(lián)合體允懂,里面只包含64位數(shù)據(jù)蕾总,但是會根據(jù)不同的情況,64位數(shù)據(jù)表示方式有所區(qū)別递雀。
接下來就是這個結(jié)構(gòu)體提供給外部使用的方法

//部分objc_object 結(jié)構(gòu)體中的方法如下
//初始化方法
void initIsa(Class cls /*nonpointer=false*/);
void initClassIsa(Class cls /*nonpointer=maybe*/);
void initProtocolIsa(Class cls /*nonpointer=maybe*/);
void initInstanceIsa(Class cls, bool hasCxxDtor);

//isa 類型判斷方法
bool hasNonpointerIsa();
bool isTaggedPointer();
bool isBasicTaggedPointer();
bool isExtTaggedPointer();

//內(nèi)存管理相關(guān)方法
id retain();
void release();
id autorelease();

Class 類型

Class 類型在runtime源碼定義為

typedef struct objc_class *Class;

objc_class 結(jié)構(gòu)體

objc_class 繼承自 objc_object蚀浆,在runtime的部分代碼如下

// objc_class繼承于objc_object,因此
// objc_class中也有isa結(jié)構(gòu)體
struct objc_class : objc_object {
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    class_rw_t *data() {
        return bits.data();
    }
    void setData(class_rw_t *newData) {
        bits.setData(newData);
    }
    ......
    bool isARC() {
        return data()->ro->flags & RO_IS_ARC;
    }
    ......
}

objc_class 結(jié)構(gòu)體其實就是我們平時所說的類對象市俊,有指向父類的isa指針(superclass)秕衙,有方法緩存cache_t,有類的方法鹦牛,屬性勇吊,協(xié)議(保存在class_rw_t中)等信息汉规。

cache_t 結(jié)構(gòu)體

先看看cache_t 結(jié)構(gòu)體的源碼

struct cache_t {
    struct bucket_t *_buckets; //散列表
    mask_t _mask;   //散列表的長度 -1
    mask_t _occupied; //已經(jīng)緩存的數(shù)量
    ......
    
}

bucket_t 在arm64的定義為

struct bucket_t {
private:
    // IMP-first is better for arm64e ptrauth and no worse for arm64.
    // SEL-first is better for armv7* and i386 and x86_64.
#if __arm64__
    MethodCacheIMP _imp;
    cache_key_t _key;
#else

可以看到cache_t 是利用散列表來緩存bucket_t對象,而bucket_t保存了緩存key和方法調(diào)用的 IMP指針

class_data_bits_t 結(jié)構(gòu)體

struct class_data_bits_t {

    // Values are the FAST_ flags above.
    uintptr_t bits;
    ......
}
  • 相當(dāng)于 unsigned long bits; 占64位 bits實際上是一個地址(是一個對象的指針晶伦,可以指向class_ro_t婚陪,也可以指向class_rw_t)频祝,其實是對class_rw_t 結(jié)構(gòu)體的一個簡單封裝,提供一些操作class_rw_t的方法
  • 為什么要這個設(shè)計沽一,有待驗證铣缠??

class_rw_t 結(jié)構(gòu)體

struct class_rw_t {
    // Be warned that Symbolication knows the layout of this structure.
    uint32_t flags;
    uint32_t version;
    const class_ro_t *ro;
    // 方法信息
    method_array_t methods;
    // 屬性信息
    property_array_t properties;
    // 協(xié)議信息
    protocol_array_t protocols;
    ......
}

可以看到class_rw_t 結(jié)構(gòu)體的rw(readwrite)表示可讀寫的意思拙友,這里保存了類的方法遗契,屬性病曾,協(xié)議等信息泰涂,class_ro_t 結(jié)構(gòu)體也保存了以上信息,但是他是不可讀寫的(ro,readonly)从绘,所以在運(yùn)行時會把分類的方法是牢,協(xié)議等信息動態(tài)添加到這里。

method_t 結(jié)構(gòu)體

struct method_t {
    SEL name;
    const char *types;
    MethodListIMP imp;
    struct SortBySELAddress :
        public std::binary_function<const method_t&,
                                    const method_t&, bool>
    {
        bool operator() (const method_t& lhs,
                         const method_t& rhs)
        { return lhs.name < rhs.name; }
    };
};

method_t 有三個成員變量

  • SEL name 也就是我們調(diào)用方法的時候批什,傳遞的選擇子selector
  • const char *types; 方法的返回值和參數(shù)驻债,比如@v等字符串(類型編碼)
  • MethodListIMP imp; 函數(shù)體(IMP)

property_t結(jié)構(gòu)體

struct property_t {
    const char *name;
    const char *attributes;
};
  • name 屬性名字
  • attributes 屬性修飾符(nonatomic,readonly,strong等)

9合呐、@dynamic和@synthesize

這兩個關(guān)鍵字都是和@property 相關(guān)的笙以,如果這兩個關(guān)鍵字都沒有寫,只寫了@property來聲明屬性翩伪,那么默認(rèn)就是@synthesize var = _var;
如果添加了@dynamic 關(guān)鍵字缘屹,那么就是告訴編譯器自己手動生成setter和getter方法(如果是readonly就只需生成getter)侠仇,如何你沒有生動生成逻炊,那么運(yùn)行時就不會報錯。

額外:
.m文件反編譯cpp文件的指令
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m

UI相關(guān)

1豹休、UIView和CALayer的關(guān)系

持續(xù)更新ing

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末威根,一起剝皮案震驚了整個濱河市视乐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌留美,老刑警劉巖妄辩,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡症歇,警方通過查閱死者的電腦和手機(jī)谭梗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門激捏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來远舅,“玉大人痕钢,你說我怎么就攤上這事⌒蛄” “怎么了任连?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長例诀。 經(jīng)常有香客問我随抠,道長,這世上最難降的妖魔是什么繁涂? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任拱她,我火速辦了婚禮扔罪,結(jié)果婚禮上秉沼,老公的妹妹穿的比我還像新娘。我一直安慰自己矿酵,他們只是感情好氧猬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坏瘩,像睡著了一般盅抚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上倔矾,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天妄均,我揣著相機(jī)與錄音,去河邊找鬼哪自。 笑死丰包,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的壤巷。 我是一名探鬼主播邑彪,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼胧华!你這毒婦竟也來了寄症?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矩动,失蹤者是張志新(化名)和其女友劉穎有巧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悲没,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡篮迎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甜橱。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逊笆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岂傲,到底是詐尸還是另有隱情难裆,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布譬胎,位于F島的核電站,受9級特大地震影響命锄,放射性物質(zhì)發(fā)生泄漏堰乔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一脐恩、第九天 我趴在偏房一處隱蔽的房頂上張望镐侯。 院中可真熱鬧,春花似錦驶冒、人聲如沸苟翻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崇猫。三九已至,卻和暖如春需忿,著一層夾襖步出監(jiān)牢的瞬間诅炉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工屋厘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涕烧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓汗洒,卻偏偏與公主長得像议纯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溢谤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一瞻凤、C 程序的內(nèi)存結(jié)構(gòu) 因為 Objetive-C 是基于 C 之上的,為了能充分了解 OC 中的 Stack 和...
    Xxxxxb_閱讀 978評論 0 3
  • 從 NSObject 的初始化了解 isa 代替 isa 指針的是結(jié)構(gòu)體 isa_t, 這個結(jié)構(gòu)體中"包含"了當(dāng)前...
    name007閱讀 626評論 0 0
  • iOS 基礎(chǔ)知識概述 基本修飾屬性 assion-基本用于修飾基本數(shù)據(jù)類型 如 int 等 是弱引用 copyco...
    浮萍向北閱讀 371評論 0 5
  • 技術(shù)基礎(chǔ) 1世杀、我們說的Objective-C是動態(tài)運(yùn)行時語言是什么意思鲫构? 答:OC可以通過Runtime這個運(yùn)行時...
    慌莫染閱讀 1,356評論 0 4
  • 1、weak關(guān)鍵字的作用 weak的作用是弱引用玫坛,它修飾的對象在釋放時會置為nil结笨,避免錯誤的內(nèi)存訪問。一般用于d...
    Lorne_coder閱讀 750評論 0 7