<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[柠檬技术栈]]></title><description><![CDATA[总有一天可以躺平的ヾ(◍°∇°◍)ﾉﾞ]]></description><link>https://lemonlie.com/</link><image><url>https://lemonlie.com/favicon.png</url><title>柠檬技术栈</title><link>https://lemonlie.com/</link></image><generator>Ghost 5.74</generator><lastBuildDate>Sun, 14 Jun 2026 10:42:11 GMT</lastBuildDate><atom:link href="https://lemonlie.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Category和关联对象]]></title><description><![CDATA[<p>Category&#x4E5F;&#x5C31;&#x662F;&#x5206;&#x7C7B;&#xFF0C;&#x53EF;&#x4EE5;&#x5728;&#x6CA1;&#x6709;&#x7C7B;&#x5B9A;&#x4E49;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x4E3A;&#x73B0;&#x6709;&#x7C7B;&#x6DFB;&#x52A0;&#x65B9;&#x6CD5;&#x3001;&#x5C5E;&#x6027;&#x3001;&#x534F;&#x8BAE;&#xFF0C;&#x4F17;&#x6240;&#x5468;&#x77E5;&#x662F;&#x4E0D;&#x80FD;&#x589E;&#x52A0;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x7684;&#xFF0C;&#x4F46;</p>]]></description><link>https://lemonlie.com/category-he-guan-lian-dui-xiang/</link><guid isPermaLink="false">65672ee96c00b44e30765796</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Wed, 27 Jul 2022 08:47:10 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1498847559558-1e4b1a7f7a2f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDEzfHxyYWlufGVufDB8fHx8MTY1ODkxMTQwMg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1498847559558-1e4b1a7f7a2f?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDEzfHxyYWlufGVufDB8fHx8MTY1ODkxMTQwMg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Category&#x548C;&#x5173;&#x8054;&#x5BF9;&#x8C61;"><p>Category&#x4E5F;&#x5C31;&#x662F;&#x5206;&#x7C7B;&#xFF0C;&#x53EF;&#x4EE5;&#x5728;&#x6CA1;&#x6709;&#x7C7B;&#x5B9A;&#x4E49;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x4E3A;&#x73B0;&#x6709;&#x7C7B;&#x6DFB;&#x52A0;&#x65B9;&#x6CD5;&#x3001;&#x5C5E;&#x6027;&#x3001;&#x534F;&#x8BAE;&#xFF0C;&#x4F17;&#x6240;&#x5468;&#x77E5;&#x662F;&#x4E0D;&#x80FD;&#x589E;&#x52A0;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x7684;&#xFF0C;&#x4F46;&#x662F;&#x662F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x7ED9;&#x7C7B;&#x589E;&#x52A0;&#x7684;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>struct category_t {
    const char *name;
    classref_t cls;
    WrappedPtr&lt;method_list_t, method_list_t::Ptrauth&gt; instanceMethods;
    WrappedPtr&lt;method_list_t, method_list_t::Ptrauth&gt; classMethods;
    struct protocol_list_t *protocols;
    struct property_list_t *instanceProperties;
    // Fields below this point are not always present on disk.
    struct property_list_t *_classProperties;

    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) return classMethods;
        else return instanceMethods;
    }

    property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
    
    protocol_list_t *protocolsForMeta(bool isMeta) {
        if (isMeta) return nullptr;
        else return protocols;
    }
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x8FD9;&#x91CC;&#x9762;&#x53EA;&#x6709;&#x65B9;&#x6CD5;&#x3001;&#x534F;&#x8BAE;&#x3001;&#x5C5E;&#x6027;&#x5217;&#x8868;&#xFF0C;&#x5E76;&#x6CA1;&#x6709;&#x5B58;&#x50A8;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x7684;&#x5730;&#x65B9;&#x3002;&#x6240;&#x4EE5;&#x5C31;&#x7528;&#x5230;&#x4E86;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x53BB;&#x5B58;&#x50A8;&#x8FD9;&#x4E9B;&#x6570;&#x636E;&#x3002;</p><p>&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x4E3B;&#x8981;&#x901A;&#x8FC7;&#x4EE5;&#x4E0B;&#x4E09;&#x4E2A;&#x51FD;&#x6570;&#x8FDB;&#x884C;&#x5B9E;&#x73B0;</p><!--kg-card-begin: markdown--><pre><code>//&#x8BBE;&#x7F6E;
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
{
    _object_set_associative_reference(object, key, value, policy);
}
//&#x83B7;&#x53D6;
id objc_getAssociatedObject(id object, const void *key)
{
    return _object_get_associative_reference(object, key);
}
//&#x5220;&#x9664;
void objc_removeAssociatedObjects(id object) 
{
    if (object &amp;&amp; object-&gt;hasAssociatedObjects()) {
        _object_remove_associations(object, /*deallocating*/false);
    }
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5148;&#x770B;&#x4E0B;objc_AssociationPolicy &#x7B56;&#x7565;&#x7684;&#x5B9A;&#x4E49;</p><!--kg-card-begin: markdown--><pre><code>typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /**&lt; Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**&lt; Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**&lt; Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**&lt; Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**&lt; Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x91CC;&#x5206;&#x522B;&#x63D0;&#x4F9B;&#x4E86;weak&#x3001;strong&#x3001;copy&#x5BF9;&#x5E94;&#x7684;&#x7B56;&#x7565;&#x3002;&#x600E;&#x4E48;&#x4F7F;&#x7528;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x591A;&#x8BF4;&#x660E;&#x4E86;&#xFF0C;&#x4E3B;&#x8981;&#x770B;&#x4E0B;&#x5185;&#x90E8;&#x662F;&#x600E;&#x4E48;&#x5B9E;&#x73B0;&#x7684;&#x3002;</p><p>objc_setAssociatedObject&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#x8C03;&#x7528;&#x4E86;object_set_associative_reference&#x65B9;&#x6CD5;&#xFF0C;&#x65B9;&#x6CD5;&#x6BD4;&#x8F83;&#x957F;&#xFF0C;&#x4E00;&#x6BB5;&#x6BB5;&#x5206;&#x6790;</p><!--kg-card-begin: markdown--><pre><code>void
_object_set_associative_reference(id object, const void *key, id value, uintptr_t policy)
{
    // This code used to work when nil was passed for object and key. Some code
    // probably relies on that to not crash. Check and handle it explicitly.
    // rdar://problem/44094390
    if (!object &amp;&amp; !value) return;

    if (object-&gt;getIsa()-&gt;forbidsAssociatedObjects())
        _objc_fatal(&quot;objc_setAssociatedObject called on instance (%p) of class %s which does not allow associated objects&quot;, object, object_getClassName(object));

    DisguisedPtr&lt;objc_object&gt; disguised{(objc_object *)object};
    ObjcAssociation association{policy, value};

    // retain the new value (if any) outside the lock.
    association.acquireValue();
</code></pre>
<!--kg-card-end: markdown--><p>&#x5148;&#x5224;&#x65AD;&#x5BF9;&#x8C61;&#x548C;&#x8BBE;&#x7F6E;&#x7684;&#x503C;&#x662F;&#x5426;&#x4E3A;&#x7A7A;&#xFF0C;&#x7A7A;&#x7684;&#x8BDD;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x3002;&#x518D;&#x5224;&#x65AD;&#x5BF9;&#x8C61;&#x662F;&#x5426;&#x7981;&#x6B62;&#x8BBE;&#x7F6E;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x3002;DisguisedPtr&#x7C7B;&#x7684;disguised&#x6307;&#x9488;&#xFF0C;DisguisedPtr&#x662F;&#x4E3A;&#x4E86;&#x662F;&#x4E3A;&#x4E86;&#x8EB2;&#x8FC7;&#x5185;&#x5B58;&#x6CC4;&#x6F0F;&#x5DE5;&#x5177;&#x7684;&#x68C0;&#x67E5;&#x3002;&#x7136;&#x540E;&#x7528;policy&#x548C;valus&#x521D;&#x59CB;&#x5316;ObjcAssociation&#x7C7B;&#x578B;&#x5BF9;&#x8C61;&#xFF0C;&#x518D;&#x8C03;&#x7528;&#x5BF9;&#x8C61;&#x7684;acquireValue&#x65B9;&#x6CD5;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>class ObjcAssociation {
    uintptr_t _policy;
    id _value;
    &#x7701;&#x7565;&#x90E8;&#x5206;&#x4EE3;&#x7801;
    inline void acquireValue() {
            if (_value) {
                switch (_policy &amp; 0xFF) {
                case OBJC_ASSOCIATION_SETTER_RETAIN:
                    _value = objc_retain(_value);
                    break;
                case OBJC_ASSOCIATION_SETTER_COPY:
                    _value = ((id(*)(id, SEL))objc_msgSend)(_value, @selector(copy));
                    break;
                }
            }
        }
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x662F;&#x6839;&#x636E;&#x7B56;&#x7565;&#x6267;&#x884C;value&#x7684;retain&#x8FD8;&#x662F;copy&#x3002;</p><!--kg-card-begin: markdown--><pre><code>bool isFirstAssociation = false;
    {
        AssociationsManager manager;
        AssociationsHashMap &amp;associations(manager.get());

        if (value) {
            auto refs_result = associations.try_emplace(disguised, ObjectAssociationMap{});
            if (refs_result.second) {
                /* it&apos;s the first association we make */
                isFirstAssociation = true;
            }

            /* establish or replace the association */
            auto &amp;refs = refs_result.first-&gt;second;
            auto result = refs.try_emplace(key, std::move(association));
            if (!result.second) {
                association.swap(result.first-&gt;second);
            }
        } else {
            auto refs_it = associations.find(disguised);
            if (refs_it != associations.end()) {
                auto &amp;refs = refs_it-&gt;second;
                auto it = refs.find(key);
                if (it != refs.end()) {
                    association.swap(it-&gt;second);
                    refs.erase(it);
                    if (refs.size() == 0) {
                        associations.erase(refs_it);

                    }
                }
            }
        }
    }
</code></pre>
<!--kg-card-end: markdown--><p>1&#x3001;&#x5B9A;&#x4E49;&#x662F;&#x5426;&#x662F;&#x7B2C;&#x4E00;&#x6B21;&#x8BBE;&#x7F6E;&#x5173;&#x8054;&#x5BF9;&#x8C61;isFirstAssociation = false</p><p>2&#x3001;&#x83B7;&#x53D6;AssociationsManager&#xFF0C;&#x7136;&#x540E;&#x901A;&#x8FC7;manager&#x83B7;&#x53D6;&#x5168;&#x5C40;AssociationsHashMap</p><!--kg-card-begin: markdown--><pre><code>class AssociationsManager {
    using Storage = ExplicitInitDenseMap&lt;DisguisedPtr&lt;objc_object&gt;, ObjectAssociationMap&gt;;
    static Storage _mapStorage;

public:
    AssociationsManager()   { AssociationsManagerLock.lock(); }
    ~AssociationsManager()  { AssociationsManagerLock.unlock(); }

    AssociationsHashMap &amp;get() {
        return _mapStorage.get();
    }

    static void init() {
        _mapStorage.init();
    }
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;AssociationsHashMap&#x662F;static&#x7684; Storage&#x83B7;&#x53D6;&#x7684;&#xFF0C;&#x5168;&#x5C40;&#x552F;&#x4E00;&#x7684;&#x3002;</p><p>3&#x3001;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x5982;&#x679C;&#x5B58;&#x5728;&#xFF0C;&#x4ECE;AssociationsHashMap&#x4E2D;&#x901A;&#x8FC7;&#x5BF9;&#x8C61;&#x6307;&#x9488;&#x83B7;&#x53D6;ObjectAssociationMap</p><!--kg-card-begin: markdown--><pre><code>template &lt;typename... Ts&gt;
std::pair&lt;iterator, bool&gt; try_emplace(const KeyT &amp;Key, Ts &amp;&amp;... Args) {
    BucketT *TheBucket;
    if (LookupBucketFor(Key, TheBucket))
      return std::make_pair(
               makeIterator(TheBucket, getBucketsEnd(), true),
               false); // Already in map.

    // Otherwise, insert the new element.
    TheBucket = InsertIntoBucket(TheBucket, Key, std::forward&lt;Ts&gt;(Args)...);
    return std::make_pair(
             makeIterator(TheBucket, getBucketsEnd(), true),
             true);
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5982;&#x679C;&#x4E4B;&#x524D;&#x8BBE;&#x7F6E;&#x8FC7;&#xFF0C;&#x901A;&#x8FC7;&#x67E5;&#x627E;&#x83B7;&#x53D6;&#x540E;&#x8FD4;&#x56DE;&#xFF0C;&#x4E0D;&#x5B58;&#x5728;&#x521B;&#x5EFA;&#x540E;&#x8FD4;&#x56DE;&#x3002;</p><p>4&#x3001;&#x5224;&#x65AD;&#x5982;&#x679C;&#x662F;&#x7B2C;&#x4E00;&#x6B21;&#x8BBE;&#x7F6E;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#xFF0C;&#x5C06;isFirstAssociation&#x8D4B;&#x503C;true</p><p>5&#x3001;&#x518D;&#x5C06;ObjcAssociation&#x5B58;&#x50A8;&#x5230;ObjectAssociationMap&#x4E2D;&#xFF0C;&#x4EE5;key&#x4F5C;&#x4E3A;&#x952E;&#x503C;&#x3002;</p><p>6&#x3001;&#x5982;&#x679C;value&#x4E0D;&#x5B58;&#x5728;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x901A;&#x8FC7;&#x5BF9;&#x8C61;&#x6307;&#x9488;&#x4ECE;hashmap&#x4E2D;&#x83B7;&#x53D6;map&#xFF0C;&#x7136;&#x540E;&#x518D;&#x901A;&#x8FC7;key&#x4ECE;map&#x4E2D;&#x83B7;&#x53D6;object&#xFF0C;&#x5982;&#x679C;&#x5B58;&#x5728;&#x5C31;erase&#xFF0C;&#x5982;&#x679C;map&#x7684;size&#x4E3A;&#x7A7A;&#x4E5F;erase&#x6389;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>    if (isFirstAssociation)
        object-&gt;setHasAssociatedObjects();

    // release the old value (outside of the lock).
    association.releaseHeldValue();
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x90E8;&#x5206;&#x5C31;&#x6BD4;&#x8F83;&#x7B80;&#x5355;&#x4E86;&#xFF0C;&#x5982;&#x679C;&#x662F;&#x7B2C;&#x4E00;&#x6B21;&#x8BBE;&#x7F6E;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#xFF0C;&#x5C31;&#x628A;&#x5BF9;&#x8C61;&#x7684; newisa.has_assoc&#x8BBE;&#x7F6E;&#x4E3A;true&#xFF0C;&#x65B9;&#x4FBF;&#x5BF9;&#x8C61;&#x91CA;&#x653E;&#x7684;&#x65F6;&#x5019;&#x540C;&#x65F6;&#x91CA;&#x653E;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#xFF0C;&#x6700;&#x540E;release&#x65E7;&#x7684;value&#x3002;</p><p>&#x518D;&#x770B;&#x4E0B;objc_getAssociatedObject&#x91CC;&#x9762;&#x662F;&#x8C03;&#x7528;&#x4E86;_object_get_associative_reference&#x65B9;&#x6CD5;</p><!--kg-card-begin: markdown--><pre><code>id
_object_get_associative_reference(id object, const void *key)
{
    ObjcAssociation association{};

    {
        AssociationsManager manager;
        AssociationsHashMap &amp;associations(manager.get());
        AssociationsHashMap::iterator i = associations.find((objc_object *)object);
        if (i != associations.end()) {
            ObjectAssociationMap &amp;refs = i-&gt;second;
            ObjectAssociationMap::iterator j = refs.find(key);
            if (j != refs.end()) {
                association = j-&gt;second;
                association.retainReturnedValue();
            }
        }
    }

    return association.autoreleaseReturnedValue();
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x91CC;&#x5F88;&#x76F4;&#x89C2;&#x7684;&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x5148;&#x58F0;&#x660E;&#x4E86;&#x4E2A;ObjcAssociation&#xFF0C;&#x7136;&#x540E;&#x521B;&#x5EFA;AssociationsManager&#xFF0C;&#x518D;&#x83B7;&#x53D6;AssociationsHashMap&#xFF0C;&#x518D;&#x901A;&#x8FC7;AssociationsHashMap&#x4EE5;object&#x4E3A;key&#x83B7;&#x53D6;ObjectAssociationMap&#xFF0C;&#x518D;&#x4EE5;key&#x83B7;&#x53D6;ObjcAssociation&#xFF0C;&#x7136;&#x540E;&#x8FD4;&#x56DE;&#x83B7;&#x53D6;&#x5230;&#x7684;&#x503C;&#x3002;</p><p>&#x7EFC;&#x4E0A;&#x53EF;&#x770B;&#x51FA;&#xFF0C;&#x5B58;&#x50A8;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-37.png" class="kg-image" alt="Category&#x548C;&#x5173;&#x8054;&#x5BF9;&#x8C61;" loading="lazy" width="1200" height="597" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-37.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-37.png 1000w, https://lemonlie.com/content/images/2022/07/image-37.png 1200w" sizes="(min-width: 720px) 720px"></figure>]]></content:encoded></item><item><title><![CDATA[内存管理-AutoreleasePool]]></title><description><![CDATA[<p>AutoreleasePool(&#x81EA;&#x52A8;&#x91CA;&#x653E;&#x6C60;)&#x662F;Objective-C&#x4E2D;&#x7684;&#x4E00;&#x79CD;&#x5185;&#x5B58;&#x81EA;&#x52A8;&#x56DE;&#x6536;&#x673A;&#x5236;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x5EF6;&#x8FDF;&#x52A0;&#x5165;AutoreleasePool&#x4E2D;&#x7684;&#x53D8;&#x91CF;release&#x7684;&#x65F6;&#x673A;&#x3002;</p><p>@autoreleasepool { ... }&#x53EF;&#x4EE5;&#x901A;&#x8FC7; clang -rewrite-objc &#x547D;&#x4EE4;&#x8F6C;&#x6210;C+</p>]]></description><link>https://lemonlie.com/nei-cun-guan-li-autoreleasepool/</link><guid isPermaLink="false">65672ee96c00b44e30765794</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Fri, 22 Jul 2022 03:23:08 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1557599443-2071a2df9c19?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDI5fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1557599443-2071a2df9c19?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDI5fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="&#x5185;&#x5B58;&#x7BA1;&#x7406;-AutoreleasePool"><p>AutoreleasePool(&#x81EA;&#x52A8;&#x91CA;&#x653E;&#x6C60;)&#x662F;Objective-C&#x4E2D;&#x7684;&#x4E00;&#x79CD;&#x5185;&#x5B58;&#x81EA;&#x52A8;&#x56DE;&#x6536;&#x673A;&#x5236;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x5EF6;&#x8FDF;&#x52A0;&#x5165;AutoreleasePool&#x4E2D;&#x7684;&#x53D8;&#x91CF;release&#x7684;&#x65F6;&#x673A;&#x3002;</p><p>@autoreleasepool { ... }&#x53EF;&#x4EE5;&#x901A;&#x8FC7; clang -rewrite-objc &#x547D;&#x4EE4;&#x8F6C;&#x6210;C++&#x4EE3;&#x7801;&#x5982;&#x4E0B;</p><pre><code>/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

}
</code></pre>
<p>&#x7136;&#x540E;&#x53EF;&#x4EE5;&#x4ECE;objc&#x6E90;&#x7801;&#x4E2D;&#x627E;&#x5230;__AtAutoreleasePool&#x7684;&#x5B9A;&#x4E49;</p><pre><code>struct __AtAutoreleasePool {
  __AtAutoreleasePool() {
      atautoreleasepoolobj = objc_autoreleasePoolPush();
  }
  ~__AtAutoreleasePool() {
      objc_autoreleasePoolPop(atautoreleasepoolobj);
  }
  void * atautoreleasepoolobj;
};
</code></pre>
<p>&#x8FD9;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x5148;&#x901A;&#x8FC7;&#x6784;&#x9020;&#x51FD;&#x6570;&#x6784;(__AtAutoreleasePool)&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x6808;&#x53D8;&#x91CF;__autoreleasepool&#xFF0C;&#x7136;&#x540E;&#x5728;&#x5927;&#x62EC;&#x53F7;&#x7ED3;&#x675F;&#x7684;&#x65F6;&#x5019;&#x901A;&#x8FC7;&#x6790;&#x6784;&#x51FD;&#x6570;(~__AtAutoreleasePool)&#x9500;&#x6BC1;__autoreleasepool&#x53D8;&#x91CF;&#xFF0C;&#x8FD9;&#x91CC;&#x5229;&#x7528;&#x4E86;&#x53D8;&#x91CF;&#x58F0;&#x660E;&#x548C;&#x81EA;&#x52A8;&#x53D8;&#x91CF;&#x5728;&#x4EE3;&#x7801;&#x5757;&#x7ED3;&#x675F;&#x540E;&#x81EA;&#x52A8;&#x9500;&#x6BC1;&#x7684;&#x7279;&#x6027;&#x3002;&#x6240;&#x4EE5;@autoreleasepool { ... }&#x76F8;&#x5F53;&#x4E8E;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;</p><pre><code>{
   atautoreleasepoolobj = objc_autoreleasePoolPush();
   //AutoreleasePool&#x4E2D;&#x7684;&#x5176;&#x4ED6;&#x4EE3;&#x7801;
   objc_autoreleasePoolPop(atautoreleasepoolobj);
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x5206;&#x522B;&#x8C03;&#x7528;&#x4E86; objc_autoreleasePoolPush &#x548C; objc_autoreleasePoolPop &#x51FD;&#x6570;&#x3002;&#x5728;&#x6E90;&#x7801;&#x4E2D;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x51FD;&#x6570;&#x5B9E;&#x73B0;</p><pre><code>void *objc_autoreleasePoolPush(void)
{
    return AutoreleasePoolPage::push();
}

void objc_autoreleasePoolPop(void *ctxt)
{
    AutoreleasePoolPage::pop(ctxt);
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8FD9;&#x91CC;&#x5206;&#x522B;&#x8C03;&#x7528;&#x4E86;AutoreleasePoolPage&#x7684;push&#x548C;pop&#x7C7B;&#x65B9;&#x6CD5;&#x3002;&#x800C;AutoreleasePoolPage&#x7EE7;&#x627F;&#x4E8E;AutoreleasePoolPageData&#x7684;&#x7ED3;&#x6784;&#x4F53;&#x3002;</p><pre><code>struct AutoreleasePoolPageData
{
	magic_t const magic;
	__unsafe_unretained id *next;
	pthread_t const thread;
	AutoreleasePoolPage * const parent;
	AutoreleasePoolPage *child;
	uint32_t const depth;
	uint32_t hiwat;

	AutoreleasePoolPageData(__unsafe_unretained id* _next, pthread_t _thread, AutoreleasePoolPage* _parent, uint32_t _depth, uint32_t _hiwat)
		: magic(), next(_next), thread(_thread),
		  parent(_parent), child(nil),
		  depth(_depth), hiwat(_hiwat)
	{
	}
};
class AutoreleasePoolPage : private AutoreleasePoolPageData
{
    //&#x7701;&#x7565;
}
</code></pre>
<p>&#x4E0B;&#x9762;&#x770B;&#x4E0B;AutoreleasePoolPageData&#x6BCF;&#x4E00;&#x4E2A;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x7684;&#x4F5C;&#x7528;</p><p><strong>magic&#xFF1A;</strong>magic_t&#x7C7B;&#x578B;&#xFF0C;&#x662F;&#x7528;&#x6765;&#x68C0;&#x67E5; AutoreleasePoolPage&#x7684;&#x5185;&#x5B58;&#x6CA1;&#x6709;&#x635F;&#x574F;</p><pre><code>struct magic_t {
	static const uint32_t M0 = 0xA1A1A1A1;
#   define M1 &quot;AUTORELEASE!&quot;
	static const size_t M1_len = 12;
	uint32_t m[4];

	magic_t() {
		OBJC_ASSERT(M1_len == strlen(M1));
		OBJC_ASSERT(M1_len == 3 * sizeof(m[1]));

		m[0] = M0;
		strncpy((char *)&amp;m[1], M1, M1_len);
	}

	~magic_t() {
		volatile uint64_t *p = (volatile uint64_t *)m;
		p[0] = 0; p[1] = 0;
	}
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#x6784;&#x9020;&#x7684;&#x65F6;&#x5019;</p><pre><code>m[0]= 0xA1A1A1A1 
m[1-3] = AUTORELEASE!
</code></pre>
<p>&#x68C0;&#x67E5;&#x7684;&#x65F6;&#x5019;&#x65B9;&#x6CD5;&#x5982;&#x4E0B;&#xFF0C;&#x5224;&#x65AD;&#x7B2C;&#x4E00;&#x4E2A;&#x5B57;&#x8282;&#x662F;0xA1A1A1A1, &#x540E;&#x9762;&#x4E09;&#x4E2A;&#x5B57;&#x8282;&#x662F;AUTORELEASE! &#x5982;&#x4E0B;</p><pre><code>bool check() const {
    return (m[0] == M0 &amp;&amp; 0 == strncmp((char *)&amp;m[1], M1, M1_len));
}
</code></pre>
<p><strong>next&#xFF1A;</strong>&#x7C7B;&#x578B;&#x662F; __unsafe_unretained<strong> </strong>id *&#xFF0C;&#x5B58;&#x653E;&#x7684;&#x662F;&#x4E0B;&#x4E00;&#x4E2A;&#x88AB; autorelease &#x5BF9;&#x8C61;&#x7684;&#x6307;&#x9488;&#x5B58;&#x653E;&#x7684;&#x5730;&#x5740;&#x3002;</p><p><strong>thread&#xFF1A;</strong>&#x81EA;&#x52A8;&#x91CA;&#x653E;&#x6C60;&#x5BF9;&#x5E94;&#x7684;&#x7EBF;&#x7A0B;&#x3002;</p><p><strong>parent</strong>&#x548C;<strong>child</strong>&#xFF1A;&#x7528;&#x6765;&#x4FDD;&#x5B58;&#x524D;&#x4E00;&#x4E2A; AutoreleasePoolPage &#x548C;&#x540E;&#x4E00;&#x4E2A; AutoreleasePoolPage&#xFF0C;&#x53CC;&#x5411;&#x94FE;&#x8868;&#x7ED3;&#x6784;&#x3002;</p><p><strong>depth&#xFF1A;&#x94FE;&#x8868;&#x957F;&#x5EA6;</strong></p><p><strong>hiwat&#xFF1A;</strong>&#x4E00;&#x4E2A;&#x5728; DEBUG &#x65F6;&#x624D;&#x6709;&#x7528;&#x7684;&#x53C2;&#x6570;&#xFF0C;&#x8868;&#x793A;&#x6700;&#x9AD8;&#x8BB0;&#x5F55;&#x8FC7;&#x591A;&#x5C11;&#x5BF9;&#x8C61;&#x3002;</p><p>&#x4E0B;&#x9762;&#x770B;&#x4E0B;&#x8FD9;&#x4E9B;&#x53D8;&#x91CF;&#x662F;&#x600E;&#x4E48;&#x5B58;&#x50A8;&#x7684;&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;AutoreleasePoolPage &#x91CD;&#x8F7D;&#x4E86; new &#x64CD;&#x4F5C;&#x7B26;</p><pre><code>#define PAGE_MIN_SHIFT          12
#define PAGE_MIN_SIZE           (1 &lt;&lt; PAGE_MIN_SHIFT)
static size_t const SIZE = PAGE_MIN_SIZE;

static void * operator new(size_t size) {
    return malloc_zone_memalign(malloc_default_zone(), SIZE, SIZE);
}
</code></pre>
<p>&#x8FD9;&#x6837;&#x4E00;&#x4E2A;&#x65B0;&#x7684;AutoreleasePoolPage&#x5BF9;&#x8C61;&#x5C31;&#x9700;&#x8981; SIZE&#x5927;&#x5C0F;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x51FA;SIZE&#x7684;&#x5927;&#x5C0F;&#x4E3A;4096&#xFF0C;&#x800C;AutoreleasePoolPage&#x7684;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x5927;&#x5C0F;&#x52A0;&#x5728;&#x4E00;&#x8D77;&#x4E5F;&#x53EA;&#x6709; 56 &#x5B57;&#x8282;&#xFF0C;&#x5269;&#x4E0B;&#x591A;&#x51FA;&#x7684;&#x5C31;&#x662F;&#x5B58;&#x50A8;autorelease&#x5BF9;&#x8C61;&#x7684;&#x5730;&#x65B9;&#x3002;&#x5982;&#x4E0B;&#x56FE;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-1.png" class="kg-image" alt="&#x5185;&#x5B58;&#x7BA1;&#x7406;-AutoreleasePool" loading="lazy" width="1200" height="834" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-1.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-1.png 1000w, https://lemonlie.com/content/images/2022/07/image-1.png 1200w" sizes="(min-width: 720px) 720px"></figure><p>&#x56FE;&#x7247;&#x4E2D; begin&#x3001;end&#x65B9;&#x6CD5;&#x5B9A;&#x4E49;&#x5982;&#x4E0B;</p><pre><code>id * begin() {
    return (id *) ((uint8_t *)this+sizeof(*this));
}

id * end() {
    return (id *) ((uint8_t *)this+SIZE);
}
</code></pre>
<p>&#x63A5;&#x4E0B;&#x6765;&#x770B;AutoreleasePoolPage::push()&#x65B9;&#x6CD5;&#xFF0C;&#x5B9A;&#x4E49;&#x5982;&#x4E0B;</p><pre><code>static inline void *push() 
{
    id *dest;
    if (slowpath(DebugPoolAllocation)) {
        // Each autorelease pool starts on a new pool page.
        dest = autoreleaseNewPage(POOL_BOUNDARY);
    } else {
        dest = autoreleaseFast(POOL_BOUNDARY);
    }
    ASSERT(dest == EMPTY_POOL_PLACEHOLDER || *dest == POOL_BOUNDARY);
    return dest;
}
</code></pre>
<p>&#x5F53;slowpath(DebugPoolAllocation)&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4F1A;&#x8C03;&#x7528;autoreleaseNewPage&#x3002;&#x4E5F;&#x5C31;&#x662F;&#x5F53;Xcode&#x4E2D;&#x8BBE;&#x7F6E;&#x73AF;&#x5883;&#x53D8;&#x91CF;OBJC_DEBUG_POOL_ALLOCATION&#x4E3A;YES&#x7684;&#x65F6;&#x5019;&#x3002;</p><pre><code>OPTION( DebugPoolAllocation,      OBJC_DEBUG_POOL_ALLOCATION,      &quot;halt when autorelease pools are popped out of order, and allow heap debuggers to track autorelease pools&quot;)
</code></pre>
<p>EMPTY_POOL_PLACEHOLDER&#x548C;POOL_BOUNDARY&#x7684;&#x5B9A;&#x4E49;&#x5982;&#x4E0B;</p><pre><code>#   define EMPTY_POOL_PLACEHOLDER ((id*)1)
#   define POOL_BOUNDARY nil
</code></pre>
<p>&#x5176;&#x4ED6;&#x65F6;&#x5019;&#x8C03;&#x7528;autoreleaseFast</p><pre><code>static __attribute__((noinline))
id *autoreleaseNewPage(id obj)
{
    AutoreleasePoolPage *page = hotPage();
    if (page) return autoreleaseFullPage(obj, page);
    else return autoreleaseNoPage(obj);
}
static inline id *autoreleaseFast(id obj)
{
    AutoreleasePoolPage *page = hotPage();
    if (page &amp;&amp; !page-&gt;full()) {
        return page-&gt;add(obj);
    } else if (page) {
        return autoreleaseFullPage(obj, page);
    } else {
        return autoreleaseNoPage(obj);
    }
}
</code></pre>
<p>&#x4E24;&#x4E2A;&#x65B9;&#x6CD5;&#x4E0D;&#x540C;&#x7684;&#x5730;&#x65B9;&#x662F;&#xFF0C;Debug&#x7684;&#x65F6;&#x5019;&#x4F1A;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x5168;&#x65B0;&#x7684;AutoreleasePoolPage&#x3002;</p><p>&#x770B;hotPage&#x65B9;&#x6CD5;&#x5982;&#x4E0B;</p><pre><code>static inline AutoreleasePoolPage *hotPage() 
{
    AutoreleasePoolPage *result = (AutoreleasePoolPage *)
        tls_get_direct(key);
    if ((id *)result == EMPTY_POOL_PLACEHOLDER) return nil;
    if (result) result-&gt;fastcheck();
    return result;
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x662F;&#x4ECE;tls&#x4E2D;&#x83B7;&#x53D6;&#x4E4B;&#x524D;&#x5B58;&#x5165;&#x7684;page&#xFF0C;tls&#x662F;&#x7EBF;&#x7A0B;&#x5C40;&#x90E8;&#x5B58;&#x50A8;(Thread Local Storage)&#x7684;&#x7F29;&#x5199;&#x3002;&#x5982;&#x679C;&#x662F;EMPTY_POOL_PLACEHOLDER&#x7684;&#x8BDD;&#xFF0C;&#x8FD4;&#x56DE;nil&#xFF0C;&#x540E;&#x9762;&#x4F1A;&#x5177;&#x4F53;&#x8BF4;&#x660E;&#x5176;&#x4F5C;&#x7528;&#x3002;&#x5B58;&#x5165;&#x7684;&#x65B9;&#x6CD5;&#x5982;&#x4E0B;</p><pre><code>static inline void setHotPage(AutoreleasePoolPage *page) 
{
    if (page) page-&gt;fastcheck();
    tls_set_direct(key, (void *)page);
}
</code></pre>
<p>&#x7EE7;&#x7EED;&#x770B;autoreleaseFullPage&#x65B9;&#x6CD5;</p><pre><code>static __attribute__((noinline))
id *autoreleaseFullPage(id obj, AutoreleasePoolPage *page)
{
    // The hot page is full. 
    // Step to the next non-full page, adding a new page if necessary.
    // Then add the object to that page.
    ASSERT(page == hotPage());
    ASSERT(page-&gt;full()  ||  DebugPoolAllocation);

    do {
        if (page-&gt;child) page = page-&gt;child;
        else page = new AutoreleasePoolPage(page);
    } while (page-&gt;full());

    setHotPage(page);
    return page-&gt;add(obj);
}
</code></pre>
<p>&#x610F;&#x601D;&#x662F;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x4E2A;Page&#xFF0C;&#x6DFB;&#x52A0;&#x4E3A;&#x73B0;&#x6709;Page&#x7684;&#x5B50;&#x8282;&#x70B9;&#xFF0C;&#x518D;&#x8BBE;&#x7F6E;&#x6210;hotPage&#xFF0C;&#x7136;&#x540E;&#x6DFB;&#x52A0;&#x5BF9;&#x8C61;&#x3002;</p><p>&#x6700;&#x540E;&#x662F;autoreleaseNoPage</p><pre><code>    static __attribute__((noinline))
    id *autoreleaseNoPage(id obj)
    {
        // &quot;No page&quot; could mean no pool has been pushed
        // or an empty placeholder pool has been pushed and has no contents yet
        ASSERT(!hotPage());

        bool pushExtraBoundary = false;
        if (haveEmptyPoolPlaceholder()) {
            // We are pushing a second pool over the empty placeholder pool
            // or pushing the first object into the empty placeholder pool.
            // Before doing that, push a pool boundary on behalf of the pool 
            // that is currently represented by the empty placeholder.
            pushExtraBoundary = true;
        }
        else if (obj != POOL_BOUNDARY  &amp;&amp;  DebugMissingPools) {
            // We are pushing an object with no pool in place, 
            // and no-pool debugging was requested by environment.
            _objc_inform(&quot;MISSING POOLS: (%p) Object %p of class %s &quot;
                         &quot;autoreleased with no pool in place - &quot;
                         &quot;just leaking - break on &quot;
                         &quot;objc_autoreleaseNoPool() to debug&quot;, 
                         objc_thread_self(), (void*)obj, object_getClassName(obj));
            objc_autoreleaseNoPool(obj);
            return nil;
        }
        else if (obj == POOL_BOUNDARY  &amp;&amp;  !DebugPoolAllocation) {
            // We are pushing a pool with no pool in place,
            // and alloc-per-pool debugging was not requested.
            // Install and return the empty pool placeholder.
            return setEmptyPoolPlaceholder();
        }

        // We are pushing an object or a non-placeholder&apos;d pool.

        // Install the first page.
        AutoreleasePoolPage *page = new AutoreleasePoolPage(nil);
        setHotPage(page);
        
        // Push a boundary on behalf of the previously-placeholder&apos;d pool.
        if (pushExtraBoundary) {
            page-&gt;add(POOL_BOUNDARY);
        }
        
        // Push the requested object or pool.
        return page-&gt;add(obj);
    }
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x56E0;&#x4E3A;push&#x7684;&#x65F6;&#x5019;&#x4F20;&#x7684;&#x662F;POOL_BOUNDARY&#xFF0C;&#x8FD9;&#x91CC;&#x5E76;&#x6CA1;&#x6709;&#x521D;&#x59CB;&#x5316;&#x65B0;&#x7684;page&#xFF0C;&#x800C;&#x662F;&#x8BBE;&#x7F6E;&#x4E86;&#x4E2A;EMPTY_POOL_PLACEHOLDER&#x3002;</p><pre><code>static inline id* setEmptyPoolPlaceholder()
{
    ASSERT(tls_get_direct(key) == nil);
    tls_set_direct(key, (void *)EMPTY_POOL_PLACEHOLDER);
    return EMPTY_POOL_PLACEHOLDER;
}
</code></pre>
<p>&#x7B49;&#x6709;&#x518D;&#x6709;autorelease&#x5BF9;&#x8C61;&#x8FDB;&#x6765;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5148;&#x5224;&#x65AD;&#x6709;&#x6CA1;&#x6709;&#x5360;&#x4F4D;&#x7B26;&#xFF0C;&#x7136;&#x540E;&#x518D;&#x628A;&#x521D;&#x59CB;&#x5316;page&#x5E76;&#x4E14;&#x8BBE;&#x7F6E;&#x4E3A;hotPage&#xFF0C;&#x5E76;&#x628A;POOL_BOUNDARY&#x6DFB;&#x52A0;&#x5230;&#x5176;&#x4E2D;&#xFF0C;&#x6700;&#x540E;&#x518D;&#x6DFB;&#x52A0;&#x5BF9;&#x8C61;&#x5230;page&#x4E2D;&#x3002;</p><p>&#x5BF9;&#x8C61;&#x7684;autorelease&#x6700;&#x7EC8;&#x662F;&#x8C03;&#x7528;&#x5230;AutoreleasePoolPage&#x7684;autorelease&#x65B9;&#x6CD5;</p><pre><code>static inline id autorelease(id obj)
{
    ASSERT(!_objc_isTaggedPointerOrNil(obj));
    id *dest __unused = autoreleaseFast(obj);
#if SUPPORT_AUTORELEASEPOOL_DEDUP_PTRS
    ASSERT(!dest  ||  dest == EMPTY_POOL_PLACEHOLDER  ||  (id)((AutoreleasePoolEntry *)dest)-&gt;ptr == obj);
#else
    ASSERT(!dest  ||  dest == EMPTY_POOL_PLACEHOLDER  ||  *dest == obj);
#endif
    return obj;
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x8FD9;&#x91CC;&#x4E3B;&#x8981;&#x662F;&#x8C03;&#x7528;&#x4E86;autoreleaseFast&#x65B9;&#x6CD5;&#xFF0C;&#x66F4;&#x4E0A;&#x9762;push&#x7684;&#x65F6;&#x5019;&#x8C03;&#x7528;&#x7684;&#x65B9;&#x6CD5;&#x662F;&#x4E00;&#x6837;&#x7684;&#xFF0C;&#x53EA;&#x4E0D;&#x8FC7;&#x8FD9;&#x91CC;obj&#x662F;&#x5BF9;&#x8C61;&#x5730;&#x5740;&#xFF0C;push&#x7684;&#x65F6;&#x5019;&#x662F;POOL_BOUNDARY&#x3002;</p><p>&#x6700;&#x540E;&#x5C31;&#x662F;pop&#x65B9;&#x6CD5;</p><pre><code>    static inline void
    pop(void *token)
    {
        AutoreleasePoolPage *page;
        id *stop;
        if (token == (void*)EMPTY_POOL_PLACEHOLDER) {
            // Popping the top-level placeholder pool.
            page = hotPage();
            if (!page) {
                // Pool was never used. Clear the placeholder.
                return setHotPage(nil);
            }
            // Pool was used. Pop its contents normally.
            // Pool pages remain allocated for re-use as usual.
            page = coldPage();
            token = page-&gt;begin();
        } else {
            page = pageForPointer(token);
        }

        stop = (id *)token;
        if (*stop != POOL_BOUNDARY) {
            if (stop == page-&gt;begin()  &amp;&amp;  !page-&gt;parent) {
                // Start of coldest page may correctly not be POOL_BOUNDARY:
                // 1. top-level pool is popped, leaving the cold page in place
                // 2. an object is autoreleased with no pool
            } else {
                // Error. For bincompat purposes this is not 
                // fatal in executables built with old SDKs.
                return badPop(token);
            }
        }

        if (slowpath(PrintPoolHiwat || DebugPoolAllocation || DebugMissingPools)) {
            return popPageDebug(token, page, stop);
        }

        return popPage&lt;false&gt;(token, page, stop);
    }
</code></pre>
<p>&#x8FD9;&#x91CC;&#x9762;&#x4E3B;&#x8981;&#x662F;&#x901A;&#x8FC7;token&#x83B7;&#x53D6;&#x9700;&#x8981;pop&#x7684;Page&#xFF0C;&#x771F;&#x6B63;&#x7684;&#x64CD;&#x4F5C;&#x5728;popPage&#x65B9;&#x6CD5;&#xFF0C;&#x6A21;&#x677F;&#x4F20;&#x503C;&#x4E3A;false&#xFF0C;&#x6240;&#x4EE5;&#x53BB;&#x9664;Debug&#x76F8;&#x5173;&#x7684;&#x903B;&#x8F91;</p><pre><code>template&lt;bool allowDebug&gt;
static void
popPage(void *token, AutoreleasePoolPage *page, id *stop)
{
    page-&gt;releaseUntil(stop);
    if (page-&gt;child) {
        // hysteresis: keep one empty child if page is more than half full
        if (page-&gt;lessThanHalfFull()) {
            page-&gt;child-&gt;kill();
        }
        else if (page-&gt;child-&gt;child) {
            page-&gt;child-&gt;child-&gt;kill();
        }
    }
}
</code></pre>
<p>&#x5148;&#x770B;&#x4E0B;releaseUntil&#x65B9;&#x6CD5;&#x4E2D;&#x505A;&#x4E86;&#x4EC0;&#x4E48;</p><pre><code>void releaseUntil(id *stop) 
{
    // Not recursive: we don&apos;t want to blow out the stack 
    // if a thread accumulates a stupendous amount of garbage

    while (this-&gt;next != stop) {
        // Restart from hotPage() every time, in case -release 
        // autoreleased more objects
        AutoreleasePoolPage *page = hotPage();

        // fixme I think this `while` can be `if`, but I can&apos;t prove it
        while (page-&gt;empty()) {
            page = page-&gt;parent;
            setHotPage(page);
        }

        page-&gt;unprotect();
        AutoreleasePoolEntry* entry = (AutoreleasePoolEntry*) --page-&gt;next;
        // create an obj with the zeroed out top byte and release that
        id obj = (id)entry-&gt;ptr;
        int count = (int)entry-&gt;count;  // grab these before memset
        memset((void*)page-&gt;next, SCRIBBLE, sizeof(*page-&gt;next));
        page-&gt;protect();

        if (obj != POOL_BOUNDARY) {
            // release count+1 times since it is count of the additional
            // autoreleases beyond the first one
            for (int i = 0; i &lt; count + 1; i++) {
                objc_release(obj);
            }
        }
    }
    setHotPage(this);
}
</code></pre>
<p>&#x5927;&#x6982;&#x903B;&#x8F91;&#x4E0A;&#xFF0C;&#x5411;&#x4E0B;&#x904D;&#x5386;&#xFF0C;&#x7136;&#x540E;&#x901A;&#x8FC7;&#x5185;&#x5B58;&#x5E73;&#x79FB;&#x83B7;&#x53D6;&#x5BF9;&#x8C61;&#xFF0C;&#x5224;&#x65AD;&#x5982;&#x679C;&#x4E0D;&#x662F;&#x54E8;&#x5175;&#x5BF9;&#x8C61;&#xFF0C;&#x4F1A;&#x8C03;&#x7528;objc_release&#x7684;&#x64CD;&#x4F5C;&#x3002;&#x6700;&#x540E;&#x8BBE;&#x7F6E;&#x5F53;&#x524D;&#x9875;&#x9762;&#x4E3A;hotPage&#x3002;</p><p>&#x6700;&#x540E;&#x770B;&#x4E0B;kill</p><pre><code>void kill() 
{
    // Not recursive: we don&apos;t want to blow out the stack 
    // if a thread accumulates a stupendous amount of garbage
    AutoreleasePoolPage *page = this;
    while (page-&gt;child) page = page-&gt;child;

    AutoreleasePoolPage *deathptr;
    do {
        deathptr = page;
        page = page-&gt;parent;
        if (page) {
            page-&gt;unprotect();
            page-&gt;child = nil;
            page-&gt;protect();
        }
        delete deathptr;
    } while (deathptr != this);
}
</code></pre>
<p>&#x4E0A;&#x9762;&#x662F;&#x628A;&#x5BF9;&#x8C61;&#x90FD;&#x91CA;&#x653E;&#x4E86;&#xFF0C;&#x8FD9;&#x91CC;&#x628A;&#x4E0D;&#x9700;&#x8981;&#x7684;page&#x8BBE;&#x7F6E;&#x4E3A;nil&#x3002;</p><p>&#x7EFC;&#x4E0A;&#x6240;&#x8FF0;&#xFF1A;</p><p>1&#x3001;&#x81EA;&#x52A8;&#x91CA;&#x653E;&#x6C60;&#x7684;&#x538B;&#x6808;&#x548C;&#x51FA;&#x6808;&#xFF0C;&#x662F;&#x901A;&#x8FC7;&#x7ED3;&#x6784;&#x4F53;&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#x548C;&#x6790;&#x6784;&#x51FD;&#x6570;&#x89E6;&#x53D1;&#x7684;&#xFF0C;&#x538B;&#x6808;&#x8C03;&#x7528;objc_autoreleasePoolPush&#x51FD;&#x6570;&#xFF0C;&#x51FA;&#x6808;&#x8C03;&#x7528;objc_autoreleasePoolPop&#x51FD;&#x6570;&#x3002;</p><p>2&#x3001;&#x81EA;&#x52A8;&#x91CA;&#x653E;&#x6C60;&#x662F;&#x4E00;&#x4E2A;&#x5B58;&#x50A8;&#x6307;&#x9488;&#x7684;&#x6808;&#x7ED3;&#x6784;&#xFF0C;&#x6307;&#x9488;&#x662F;&#x4E00;&#x4E2A;&#x8981;&#x91CA;&#x653E;&#x7684;&#x5BF9;&#x8C61;&#x6216;&#x8005;&#x662F;POOL_BOUNDARY&#x81EA;&#x52A8;&#x91CA;&#x653E;&#x6C60;&#x8FB9;&#x754C;&#x3002;</p><p>3&#x3001;&#x6C60;&#x9875;&#x5927;&#x5C0F;&#x4E3A;4096&#x5B57;&#x8282;&#xFF0C;&#x6BCF;&#x4E00;&#x9875;&#x90FD;&#x5305;&#x542B;56&#x5B57;&#x8282;&#x7684;&#x6210;&#x5458;&#x53D8;&#x91CF;&#xFF0C;&#x4E00;&#x4E2A;Page&#x6700;&#x591A;&#x53EF;&#x4EE5;&#x5BB9;&#x7EB3; (4096-56) / 8 = 505&#x4E2A;autorelease&#x7684;&#x5BF9;&#x8C61;&#x3002;</p><p>&#x53EF;&#x4EE5;&#x5199;&#x4EE3;&#x7801;&#x9A8C;&#x8BC1;&#x4E0B;&#xFF0C;&#x5199;&#x4E4B;&#x524D;&#x8981;&#x5148;&#x628A;&#x5DE5;&#x7A0B;&#x8BBE;&#x7F6E;&#x4E3A;MRC&#x3002;</p><pre><code>void _objc_autoreleasePoolPrint(void);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        for (int i = 0; i &lt; 505; i++) {
            NSObject *obj = [[[NSObject alloc] init] autorelease];
        }
        _objc_autoreleasePoolPrint();
    }
    return 0;
}
</code></pre>
<p>&#x8F93;&#x5165;&#x7ED3;&#x679C;&#x5982;&#x4E0B;</p><pre><code>objc[11901]: [0x101010000]  ................  PAGE (full)  (cold)
objc[11901]: [0x101010038]  ################  POOL 0x101010038
objc[11901]: [0x101010040]       0x100c277e0  NSObject
objc[11901]: [0x101010048]       0x100c272e0  NSObject
objc[11901]: [0x101010050]       0x100c26ba0  NSObject
objc[11901]: [0x101010058]       0x100c26160  NSObject
......
objc[11927]: [0x10100d000]  ................  PAGE  (hot) 
objc[11927]: [0x10100d038]       0x100ab2920  NSObject
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x662F;POOL_BOUNDARY&#xFF0C;505&#x4E2A;&#x5BF9;&#x8C61;&#x5FAA;&#x73AF;&#x52A0;&#x5165;&#x5230;page&#x4E2D;&#xFF0C;&#x6700;&#x540E;&#x4E00;&#x4E2A;&#x7684;&#x65F6;&#x5019;page&#x6EE1;&#x4E86;&#xFF0C;&#x6240;&#x4EE5;&#x6700;&#x540E;&#x4E00;&#x4E2A;&#x52A0;&#x5230;&#x4E86;&#x65B0;&#x7684;page&#x4E2D;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[如何为macOS应用开发插件]]></title><description><![CDATA[<p><strong>&#x672C;&#x6587;&#x7AE0;&#x53EA;&#x7528;&#x4E8E;&#x5B66;&#x4E60;&#x548C;&#x4EA4;&#x6D41;&#xFF0C;&#x8F6C;&#x8F7D;&#x8BF7;&#x6CE8;&#x660E;&#x51FA;&#x5904;&#x3002;</strong></p><p>&#x73A9;&#x8FC7;&#x8D8A;&#x72F1;&#x624B;&#x673A;&#x7684;&#x5E94;&#x8BE5;&#x90FD;&#x4E86;&#x89E3;&#xFF0C;iOS&#x7684;&#x8D8A;&#x72F1;&#x63D2;&#x4EF6;&#x662F;&#x53EF;&#x4EE5;&#x4E3A;&#x7CFB;&#x7EDF;&#x6216;&#x8005;&#x5E94;&#x7528;&#x6DFB;</p>]]></description><link>https://lemonlie.com/develop-plug-in-for-mac-app/</link><guid isPermaLink="false">65672ee96c00b44e30765791</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Thu, 21 Jul 2022 03:07:12 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1559087867-ce4c91325525?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fGxpZ2h0bmluZ3xlbnwwfHx8fDE2NTgzNzI4MTA&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1559087867-ce4c91325525?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fGxpZ2h0bmluZ3xlbnwwfHx8fDE2NTgzNzI4MTA&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;"><p><strong>&#x672C;&#x6587;&#x7AE0;&#x53EA;&#x7528;&#x4E8E;&#x5B66;&#x4E60;&#x548C;&#x4EA4;&#x6D41;&#xFF0C;&#x8F6C;&#x8F7D;&#x8BF7;&#x6CE8;&#x660E;&#x51FA;&#x5904;&#x3002;</strong></p><p>&#x73A9;&#x8FC7;&#x8D8A;&#x72F1;&#x624B;&#x673A;&#x7684;&#x5E94;&#x8BE5;&#x90FD;&#x4E86;&#x89E3;&#xFF0C;iOS&#x7684;&#x8D8A;&#x72F1;&#x63D2;&#x4EF6;&#x662F;&#x53EF;&#x4EE5;&#x4E3A;&#x7CFB;&#x7EDF;&#x6216;&#x8005;&#x5E94;&#x7528;&#x6DFB;&#x52A0;&#x4E00;&#x4E9B;&#x7279;&#x8272;&#x7684;&#x529F;&#x80FD;&#x7684;&#x3002;&#x8D8A;&#x72F1;&#x63D2;&#x4EF6;&#x7684;&#x5F00;&#x53D1;&#xFF0C;&#x5DF2;&#x7ECF;&#x6709;&#x5B8C;&#x6574;&#x7684;&#x5DE5;&#x5177;&#x94FE;&#xFF0C;&#x5E76;&#x4E14;&#x63D2;&#x4EF6;&#x7684;&#x52A0;&#x8F7D;&#x8FD0;&#x884C;Substrate&#x6846;&#x67B6;&#x5DF2;&#x7ECF;&#x4E3A;&#x6211;&#x4EEC;&#x505A;&#x597D;&#x3002;</p><p>&#x66F4;&#x6539;&#x5E94;&#x7528;&#x7684;&#x529F;&#x80FD;&#x5B9E;&#x73B0;&#x6709;&#x4E24;&#x79CD;&#x65B9;&#x6CD5;&#xFF0C;&#x4E00;&#x79CD;&#x662F;&#x901A;&#x8FC7;&#x53CD;&#x7F16;&#x8BD1;&#x5DE5;&#x5177;&#x66F4;&#x6539;&#x6C47;&#x7F16;&#x4EE3;&#x7801;&#x540E;&#x751F;&#x6210;&#x65B0;&#x7684;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;&#x3002;&#x53E6;&#x4E00;&#x79CD;&#x662F;&#x5199;&#x4E00;&#x4E2A;&#x52A8;&#x6001;&#x5E93;&#xFF0C;&#x7136;&#x540E;&#x6CE8;&#x5165;&#x5230;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;&#x3002;&#x7B2C;&#x4E00;&#x79CD;&#x9002;&#x5408;&#x7B80;&#x5355;&#x7684;&#x903B;&#x8F91;&#x4FEE;&#x6539;&#xFF0C;&#x6BD5;&#x7ADF;&#x7528;&#x6C47;&#x7F16;&#x5B9E;&#x73B0;&#x529F;&#x80FD;&#x662F;&#x9700;&#x8981;&#x5F88;&#x5927;&#x7684;&#x5DE5;&#x4F5C;&#x91CF;&#x7684;&#x3002;</p><p>&#x7B2C;&#x4E8C;&#x79CD;&#x8981;&#x600E;&#x4E48;&#x6CE8;&#x5165;&#x5462;&#xFF1F;&#x4E86;&#x89E3;Mach-O &#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x7684;&#x5E94;&#x8BE5;&#x77E5;&#x9053;&#xFF0C;Mach-O &#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;Load Commands&#x4E2D;&#x7684; LC_LOAD_DYLIB &#x6807;&#x5934;&#x544A;&#x8BC9; macOS&#x5728;&#x6267;&#x884C;&#x671F;&#x95F4;&#x8981;&#x52A0;&#x8F7D;&#x54EA;&#x4E9B;&#x52A8;&#x6001;&#x5E93; (dylib)&#x3002;&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x53EA;&#x9700;&#x8981;&#x5728;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x4E2D;&#x6DFB;&#x52A0;&#x4E00;&#x6761;LC_LOAD_DYLIB&#x5C31;&#x53EF;&#x4EE5;&#x3002;&#x800C;<a href="https://github.com/Tyilo/insert_dylib?ref=lemonlie.com">insert_dylib</a>&#x5DE5;&#x5177;&#x5DF2;&#x7ECF;&#x4E3A;&#x6211;&#x4EEC;&#x5B9E;&#x73B0;&#x4E86;&#x6DFB;&#x52A0;&#x7684;&#x529F;&#x80FD;&#x3002;&#x6240;&#x4EE5;&#x73B0;&#x5728;&#x552F;&#x4E00;&#x9700;&#x8981;&#x8003;&#x8651;&#x7684;&#x5C31;&#x662F;&#x63D2;&#x4EF6;&#x5982;&#x4F55;&#x5F00;&#x53D1;&#x3002;</p><p>&#x5E9F;&#x8BDD;&#x4E0D;&#x591A;&#x8BF4;&#xFF0C;&#x73B0;&#x5728;&#x5C31;&#x4EE5;mac&#x7248;&#x7684;&#x8FC5;&#x96F7;&#x4E3A;&#x4F8B;&#x5F00;&#x53D1;&#x4E00;&#x6B3E;&#x5C5E;&#x4E8E;&#x6211;&#x4EEC;&#x81EA;&#x5DF1;&#x7684;&#x63D2;&#x4EF6;&#x3002;&#x9996;&#x5148;&#x4E0B;&#x8F7D;&#x6700;&#x65B0;&#x7248;&#x672C;&#x7684;&#x8FC5;&#x96F7;(&#x7248;&#x672C;5.0.2)&#x3002;&#x7136;&#x540E;&#x7528;Xcode&#x65B0;&#x5EFA;&#x4E00;&#x4E2A;macOS&#x4E0B;&#x7684;Framework&#xFF0C;&#x5982;&#x4E0B;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-17.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1454" height="700" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-17.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-17.png 1000w, https://lemonlie.com/content/images/2022/07/image-17.png 1454w" sizes="(min-width: 720px) 720px"></figure><p>&#x65B0;&#x5EFA;&#x5B8C;&#x76EE;&#x5F55;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x6709;Tests target &#x4E0D;&#x5F71;&#x54CD;&#x540E;&#x7EED;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-18.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1556" height="536" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-18.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-18.png 1000w, https://lemonlie.com/content/images/2022/07/image-18.png 1556w" sizes="(min-width: 720px) 720px"></figure><p>&#x7136;&#x540E;&#x65B0;&#x5EFA;&#x4E2A;.m&#x6587;&#x4EF6;(&#x6587;&#x4EF6;&#x540D;&#x968F;&#x610F;)&#xFF0C;&#x628A;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x590D;&#x5236;&#x7C98;&#x8D34;&#x8FDB;&#x53BB;</p><!--kg-card-begin: markdown--><pre><code>#import &quot;libThunderPlugin.h&quot;
#import &quot;objc/runtime.h&quot;

void lm_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
    if(originalMethod &amp;&amp; swizzledMethod) {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

@implementation NSObject (Thunder)
+ (void)hookThunder{
    lm_hookMethod(objc_getClass(&quot;XLUserInformation&quot;), @selector(initWithUserInfo:), [self class], @selector(hook_initWithUserInfo:));
    lm_hookMethod(objc_getClass(&quot;XLUserInformation&quot;), @selector(updateUserInfo:), [self class], @selector(hook_updateUserInfo:));
}
- (id)hook_initWithUserInfo:(id)arg1{
    return [self hook_initWithUserInfo:[self modify:arg1]];
}
- (void)hook_updateUserInfo:(id)arg1{
    [self hook_updateUserInfo:[self modify:arg1]];
}
- (NSDictionary *)modify:(NSDictionary *)user{
    NSDictionary *vipInfo = [[user objectForKey:@&quot;vipList&quot;] firstObject];
    NSMutableDictionary *mutableVipInfo = [vipInfo mutableCopy];
    [mutableVipInfo setValue:@&quot;1&quot; forKey:@&quot;isVip&quot;];
    [mutableVipInfo setValue:@&quot;20990131&quot; forKey:@&quot;expireDate&quot;];
    [mutableVipInfo setValue:@&quot;4&quot; forKey:@&quot;vasType&quot;];
    NSMutableDictionary *userInfo = [user mutableCopy];
    [userInfo setObject:@[mutableVipInfo] forKey:@&quot;vipList&quot;];
    return userInfo;
}
@end

static void __attribute__((constructor)) initialize(void) {
    [NSObject hookThunder];
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x518D;&#x628A;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x590D;&#x5236;&#x7C98;&#x8D34;&#x5230;.h&#x6587;&#x4EF6;&#x4E2D;</p><!--kg-card-begin: markdown--><pre><code>@interface XLUserInformation : NSObject
- (void)updateUserInfo:(id)arg1;
- (id)initWithUserInfo:(id)arg1;
@end
</code></pre>
<!--kg-card-end: markdown--><p>&#x540E;&#x7EED;&#x4F1A;&#x8BF4;&#x660E;&#x4EE3;&#x7801;&#x7684;&#x610F;&#x601D;&#x548C;&#x600E;&#x4E48;&#x83B7;&#x53D6;&#x7684;&#x3002;&#x4EE5;&#x4E0A;&#x64CD;&#x4F5C;&#x5B8C;&#x6210;&#x540E;&#x7F16;&#x8BD1;&#x8FD0;&#x884C;&#xFF0C;&#x4F1A;&#x751F;&#x6210;&#x4E00;&#x4E2A;framework&#xFF0C;&#x4F46;&#x662F;Xcode13&#x628A;Products&#x9690;&#x85CF;&#x4E86;&#xFF0C;&#x5E76;&#x4E0D;&#x80FD;&#x5F88;&#x4FBF;&#x6377;&#x7684;&#x627E;&#x5230;&#x751F;&#x6210;&#x7684;&#x52A8;&#x6001;&#x5E93;&#x3002;</p><p>&#x8FD9;&#x65F6;&#x5019;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x6309;&#x7167;&#x4EE5;&#x4E0B;&#x6B65;&#x9AA4;&#x53EF;&#x4EE5;&#x4F7F;Products&#x6587;&#x4EF6;&#x663E;&#x793A;&#x51FA;&#x6765;&#x3002;</p><p>1&#x3001;&#x627E;&#x5230;&#x9879;&#x76EE;&#x5DE5;&#x7A0B;&#x6587;&#x4EF6;&#xFF0C;&#x53F3;&#x952E;&#x70B9;&#x51FB;libThunderPlugin.xcodeproj -&gt; &#x9009;&#x62E9;&#x663E;&#x793A;&#x5305;&#x5185;&#x5BB9;</p><p>2&#x3001;&#x53CC;&#x51FB;&#x6253;&#x5F00;project.pbxproj&#x6587;&#x4EF6;&#xFF0C;&#x5728;&#x6587;&#x4EF6;&#x4E2D;&#x641C;&#x7D22;productRefGroup&#x5173;&#x952E;&#x5B57;</p><p>3&#x3001;&#x5C06;productRefGroup&#x5BF9;&#x5E94;&#x7684;&#x503C;&#x6539;&#x6210;&#x548C;mainGroup&#x76F8;&#x540C;&#x5373;&#x53EF;&#x3002;</p><p>&#x6539;&#x5B8C;&#x540E;Xcode&#x4F1A;&#x81EA;&#x52A8;&#x5237;&#x65B0;&#xFF0C;&#x663E;&#x793A;&#x51FA;Products&#x76EE;&#x5F55;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-19.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1266" height="522" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-19.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-19.png 1000w, https://lemonlie.com/content/images/2022/07/image-19.png 1266w" sizes="(min-width: 720px) 720px"></figure><p>&#x7136;&#x540E;&#x53F3;&#x952E;&#x751F;&#x6210;&#x7684;framework&#xFF0C;&#x70B9;&#x51FB; Show in Finder&#xFF0C;&#x7136;&#x540E;&#x628A;framework&#x590D;&#x5236;&#x5230;&#x8FC5;&#x96F7;&#x7684;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;&#x540C;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x76EE;&#x5F55;&#x4E3A; /Applications/Thunder.app/Contents/MacOS&#x3002;</p><p>framework&#x6709;&#x4E86;&#xFF0C;&#x4E0B;&#x9762;&#x5C31;&#x662F;&#x6CE8;&#x5165;&#x5230;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;&#x3002;&#x53BB;Github&#x4E0A;&#x4E0B;&#x8F7D;insert_dylib&#x4EE3;&#x7801;&#xFF0C;&#x7F16;&#x8BD1;&#x5F97;&#x5230;insert_dylib&#x6587;&#x4EF6;&#x3002;&#x540C;&#x6837;&#x590D;&#x5236;&#x5230;&#x8FC5;&#x96F7;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;&#x540C;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x518D;&#x628A;Thunder&#x6539;&#x6210;Thunder_backup&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-21.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1062" height="366" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-21.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-21.png 1000w, https://lemonlie.com/content/images/2022/07/image-21.png 1062w" sizes="(min-width: 720px) 720px"></figure><p>&#x7136;&#x540E;&#x6253;&#x5F00;&#x7EC8;&#x7AEF;&#xFF0C;&#x8FDB;&#x5165;&#x5230;&#x8FD9;&#x4E2A;&#x76EE;&#x5F55;&#x4E0B;&#x9762;&#xFF0C;&#x6267;&#x884C;&#x5982;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>./insert_dylib --all-yes /Applications/Thunder.app/Contents/MacOS/libThunderPlugin.framework/libThunderPlugin Thunder_backup Thunder
</code></pre>
<!--kg-card-end: markdown--><p>&#x51FA;&#x73B0;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#x5C31;&#x8868;&#x793A;&#x6210;&#x529F;&#x4E86;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-24.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1132" height="210" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-24.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-24.png 1000w, https://lemonlie.com/content/images/2022/07/image-24.png 1132w" sizes="(min-width: 720px) 720px"></figure><p>&#x540C;&#x65F6;&#x76EE;&#x5F55;&#x4E0B;&#x4F1A;&#x518D;&#x751F;&#x6210;&#x4E2A;Thunder&#x6587;&#x4EF6;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-23.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1144" height="396" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-23.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-23.png 1000w, https://lemonlie.com/content/images/2022/07/image-23.png 1144w" sizes="(min-width: 720px) 720px"></figure><p>&#x8FD9;&#x65F6;&#x5019;&#x518D;&#x6253;&#x5F00;&#x8FC5;&#x96F7;&#xFF0C;&#x767B;&#x5F55;&#x8D26;&#x53F7;&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x5DF2;&#x7ECF;&#x6210;&#x4E3A;SVIP&#x4E86;&#xFF0C;&#x5E76;&#x4E14;&#x6709;&#x6548;&#x671F;&#x5230;2099&#x5E74;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-25.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1010" height="368" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-25.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-25.png 1000w, https://lemonlie.com/content/images/2022/07/image-25.png 1010w" sizes="(min-width: 720px) 720px"></figure><p>&#x4E0D;&#x8FC7;&#x8FD9;&#x4EC5;&#x4EC5;&#x662F;&#x663E;&#x793A;&#x800C;&#x5DF2;&#xFF0C;&#x5E76;&#x6CA1;&#x6709;&#x5B9E;&#x9645;&#x4F5C;&#x7528;&#x3002;&#x5176;&#x4ED6;&#x529F;&#x80FD;&#x611F;&#x5174;&#x8DA3;&#x81EA;&#x5DF1;&#x7814;&#x7A76;&#xFF0C;&#x8FD9;&#x91CC;&#x4EC5;&#x4F5C;&#x4E3A;&#x4F8B;&#x5B50;&#x3002;</p><p>&#x4E0B;&#x9762;&#x5F00;&#x59CB;&#x8BB2;&#x4EE3;&#x7801;&#xFF0C;&#x505A;iOS&#x5F00;&#x53D1;&#x7684;&#x5E94;&#x8BE5;&#x53EF;&#x4EE5;&#x770B;&#x61C2;&#xFF0C;&#x4E0A;&#x9762;&#x7684;&#x4EE3;&#x7801;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x901A;&#x8FC7;runtime&#x66FF;&#x6362;&#x539F;&#x6709;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#xFF0C;&#x66F4;&#x6539;&#x53C2;&#x6570;&#x4EE5;&#x5B9E;&#x73B0;&#x663E;&#x793A;&#x7684;&#x6548;&#x679C;&#x3002;&#x4F46;&#x662F;&#x8FD9;&#x91CC;&#x7684;&#x91CD;&#x70B9;&#x662F;&#x600E;&#x4E48;&#x53BB;&#x627E;&#x66FF;&#x6362;&#x90A3;&#x4E2A;&#x65B9;&#x6CD5;&#xFF0C;&#x66F4;&#x6539;&#x54EA;&#x4E9B;&#x53C2;&#x6570;&#x3002;</p><p>&#x5E94;&#x7528;&#x7684;&#x65B9;&#x6CD5;&#x548C;&#x7C7B;&#x4FE1;&#x606F;&#x5B58;&#x5728;&#x4E8E;Mach-O &#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x662F;&#x53EF;&#x4EE5;&#x4ECE;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x4E2D;&#x63D0;&#x53D6;&#x8FD9;&#x4E9B;&#x4FE1;&#x606F;&#x7684;&#x3002;&#x4E0B;&#x9762;&#x4ECB;&#x7ECD;&#x4E00;&#x6B3E;&#x5DE5;&#x5177;<a href="https://github.com/nygard/class-dump?ref=lemonlie.com">class-dump</a>&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x4F7F;&#x6211;&#x4EEC;&#x5FEB;&#x901F;&#x7684;&#x83B7;&#x53D6;&#x5230;&#x5E94;&#x7528;&#x7684;&#x5934;&#x6587;&#x4EF6;&#x4FE1;&#x606F;&#x3002;</p><p>&#x540C;&#x6837;&#x548C;insert_dylib&#x4E00;&#x6837;&#xFF0C;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x4E0B;&#x8F7D;&#x6E90;&#x7801;&#xFF0C;&#x7F16;&#x8BD1;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;&#x3002;&#x5982;&#x679C;&#x5B89;&#x88C5;&#x4E86;MonkeyDev&#x7684;&#x5C31;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x4F7F;&#x7528;&#x3002;&#x6253;&#x5F00;&#x7EC8;&#x7AEF;&#xFF0C;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x83B7;&#x53D6;&#x5934;&#x6587;&#x4EF6;</p><!--kg-card-begin: markdown--><pre><code>class-dump -H /Applications/Thunder.app/Contents/MacOS/Thunder -o ~/Desktop/Thunder.h
</code></pre>
<!--kg-card-end: markdown--><p>-H&#x662F;&#x83B7;&#x53D6;&#x5934;&#x6587;&#x4EF6;&#xFF0C;-o &#x662F;&#x6307;&#x5B9A;&#x5934;&#x6587;&#x4EF6;&#x7684;&#x76EE;&#x5F55;&#xFF0C;&#x4E0D;&#x6307;&#x5B9A;&#x5C31;&#x662F;&#x5F53;&#x524D;&#x6587;&#x4EF6;&#x5939;&#x3002;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x591A;&#x505A;&#x4ECB;&#x7ECD;&#x3002;&#x5B8C;&#x6210;&#x540E;&#x627E;&#x5230;Thunder.h&#x76EE;&#x5F55;&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x6709;&#x597D;&#x591A;&#x6587;&#x4EF6;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-26.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1102" height="440" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-26.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-26.png 1000w, https://lemonlie.com/content/images/2022/07/image-26.png 1102w" sizes="(min-width: 720px) 720px"></figure><p>&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x8981;&#x600E;&#x4E48;&#x627E;&#x5462;&#xFF1F;&#x4E00;&#x4E2A;&#x4E2A;&#x627E;&#x65E0;&#x7591;&#x5C31;&#x662F;&#x5927;&#x6D77;&#x635E;&#x9488;&#x3002;&#x9996;&#x5148;&#x6211;&#x4EEC;&#x8981;&#x5B66;&#x4F1A;&#x5173;&#x952E;&#x5B57;&#x641C;&#x7D22;&#xFF0C;&#x6211;&#x4EEC;&#x7684;&#x76EE;&#x7684;&#x662F;&#x8BA9;&#x7528;&#x6237;&#x72B6;&#x6001;&#x663E;&#x793A;&#x4E3A;vip&#xFF0C;&#x90A3;&#x5C31;&#x5C1D;&#x8BD5;&#x641C;&#x7D22;&#x8FD9;&#x4E2A;&#x5173;&#x952E;&#x5B57;&#x8BD5;&#x8BD5;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-27.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1220" height="528" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-27.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-27.png 1000w, https://lemonlie.com/content/images/2022/07/image-27.png 1220w" sizes="(min-width: 720px) 720px"></figure><p>&#x5F88;&#x660E;&#x663E;&#xFF0C;&#x5934;&#x6587;&#x4EF6;&#x5C11;&#x4E86;&#x5F88;&#x591A;&#x3002;&#x6253;&#x5F00;&#x7B2C;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;&#x770B;&#x770B;&#xFF0C;&#x770B;&#x540D;&#x5B57;&#x5C31;&#x77E5;&#x9053;&#x8FD9;&#x4E2A;&#x662F;&#x7528;&#x6237;&#x4FE1;&#x606F;&#x7684;&#x6A21;&#x578B;&#x7C7B;&#x3002;&#x8FD9;&#x4E2A;&#x6587;&#x4EF6;&#x6709;&#x5404;&#x79CD;&#x7528;&#x6237;&#x4FE1;&#x606F;&#x76F8;&#x5173;&#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x5E76;&#x4E14;&#x63D0;&#x4F9B;&#x4E86;&#x4E24;&#x4E2A;&#x65B9;&#x6CD5;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-28.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1284" height="386" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-28.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-28.png 1000w, https://lemonlie.com/content/images/2022/07/image-28.png 1284w" sizes="(min-width: 720px) 720px"></figure><p>&#x65B9;&#x6CD5;&#x627E;&#x5230;&#x4E86;&#xFF0C;&#x4E0B;&#x4E00;&#x6B65;&#x5C31;&#x662F;&#x9A8C;&#x8BC1;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x662F;&#x4E0D;&#x662F;&#x6211;&#x4EEC;&#x60F3;&#x8981;&#x627E;&#x7684;&#x3002;&#x5BFC;&#x5165;&#x5934;&#x6587;&#x4EF6;&#x5199;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>void lm_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
    if(originalMethod &amp;&amp; swizzledMethod) {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

@implementation NSObject (Thunder)
+ (void)hookThunder{
    lm_hookMethod(objc_getClass(&quot;XLUserInformation&quot;), @selector(initWithUserInfo:), [self class], @selector(hook_initWithUserInfo:));
    lm_hookMethod(objc_getClass(&quot;XLUserInformation&quot;), @selector(updateUserInfo:), [self class], @selector(hook_updateUserInfo:));
}
- (id)hook_initWithUserInfo:(id)arg1{
    return [self hook_initWithUserInfo:arg1];
}
- (void)hook_updateUserInfo:(id)arg1{
    [self hook_updateUserInfo:arg1];
}
@end
</code></pre>
<!--kg-card-end: markdown--><p>&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x662F;&#x901A;&#x8FC7;runtime&#x5B9E;&#x73B0;&#x4E86;&#x65B9;&#x6CD5;&#x7684;hook&#xFF0C;&#x8FD9;&#x65F6;&#x53C8;&#x6709;&#x65B0;&#x95EE;&#x9898;&#x51FA;&#x73B0;&#x4E86;&#xFF0C;&#x6211;&#x4EEC;&#x600E;&#x4E48;&#x77E5;&#x9053;&#x65B9;&#x6CD5;&#x53C2;&#x6570;&#x7C7B;&#x578B;&#xFF0C;&#x8981;&#x6539;&#x54EA;&#x4E9B;&#x503C;&#x624D;&#x80FD;&#x5B9E;&#x73B0;&#x6211;&#x4EEC;&#x7684;&#x76EE;&#x7684;&#xFF1F;&#x8FD9;&#x4E2A;&#x65F6;&#x5019;&#x5C31;&#x60F3;&#x80FD;&#x8C03;&#x8BD5;&#x5C31;&#x597D;&#x4E86;&#x3002;&#x505A;&#x8FC7;&#x8D8A;&#x72F1;&#x5F00;&#x53D1;&#x7684;&#x5E94;&#x8BE5;&#x90FD;&#x4E86;&#x89E3;&#xFF0C;&#x6211;&#x4EEC;&#x901A;&#x8FC7;&#x7ED9;debugserver&#x6DFB;&#x52A0;task_for_pid&#x6743;&#x9650;&#x5C31;&#x53EF;&#x4EE5;&#x8C03;&#x8BD5;&#x7B2C;&#x4E09;&#x65B9;&#x5E94;&#x7528;&#x4E86;&#x3002;macOS&#x4E0A;&#x6CA1;&#x90A3;&#x4E48;&#x590D;&#x6742;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x5728;&#x7F16;&#x8BD1;framework&#x7684;&#x65F6;&#x5019;&#x9009;&#x62E9;&#x542F;&#x52A8;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x8C03;&#x8BD5;&#x7684;&#x5E94;&#x7528;&#x5373;&#x53EF;&#x3002;</p><p>&#x5728;Edit Scheme&#x91CC;&#x9762;&#xFF0C;Executable&#x91CC;&#x9762;&#x9009;&#x62E9;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x8C03;&#x8BD5;&#x7684;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x56FE;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-29.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1454" height="388" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-29.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-29.png 1000w, https://lemonlie.com/content/images/2022/07/image-29.png 1454w" sizes="(min-width: 720px) 720px"></figure><p>&#x70B9;&#x51FB;Other&#xFF0C;&#x7136;&#x540E;&#x9009;&#x62E9;&#x8FC5;&#x96F7;&#x5373;&#x53EF;&#x3002;&#x5B8C;&#x6210;&#x540E;&#x4F1A;&#x53D8;&#x6210;&#x8FD9;&#x6837;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-30.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1198" height="316" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-30.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-30.png 1000w, https://lemonlie.com/content/images/2022/07/image-30.png 1198w" sizes="(min-width: 720px) 720px"></figure><p>&#x8FD9;&#x65F6;&#x5019;&#x518D;&#x70B9;&#x51FB;&#x8FD0;&#x884C;&#xFF0C;&#x5C31;&#x4F1A;&#x53D1;&#x73B0;&#x53EF;&#x4EE5;&#x8C03;&#x8BD5;&#x4E86;&#x3002;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x4E4B;&#x524D;insert_dylib&#x7684;&#x64CD;&#x4F5C;&#xFF0C;&#x4F1A;&#x6709;&#x4EE5;&#x4E0B;&#x9519;&#x8BEF;</p><!--kg-card-begin: markdown--><pre><code>Failure Reason: attach failed (Not allowed to attach to process.  Look in the console messages (Console.app), near the debugserver entries, when the attach failed.  The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.)
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#x8FD9;&#x91CC;&#x662F;&#x6743;&#x9650;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x8FD0;&#x884C;&#x7684;&#x65F6;&#x5019;&#x9A8C;&#x8BC1;&#x4E86;&#x7B7E;&#x540D;&#xFF0C;insert_dylib&#x5904;&#x7406;&#x8FC7;&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x79FB;&#x9664;&#x4E86;LC_CODE_SIGNATURE&#xFF0C;&#x6240;&#x4EE5;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x8C03;&#x8BD5;&#x3002;&#x8FD9;&#x91CC;&#x53EA;&#x9700;&#x8981;&#x66F4;&#x6539;&#x7B7E;&#x540D;&#x6DFB;&#x52A0;&#x6743;&#x9650;&#x5373;&#x53EF;&#x3002;&#x5148;&#x628A;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#x4FDD;&#x5B58;&#x5230;&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x6587;&#x4EF6;&#x540D;&#x968F;&#x610F;&#xFF0C;&#x6211;&#x7528;&#x7684;&#x662F;entitlements.xml</p><!--kg-card-begin: markdown--><pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
  &lt;dict&gt;
    &lt;key&gt;com.apple.security.cs.allow-jit&lt;/key&gt;
      &lt;true/&gt;
    &lt;key&gt;com.apple.security.cs.allow-unsigned-executable-memory&lt;/key&gt;
      &lt;true/&gt;
    &lt;key&gt;com.apple.security.cs.allow-dyld-environment-variables&lt;/key&gt;
      &lt;true/&gt;
    &lt;key&gt;com.apple.security.cs.disable-library-validation&lt;/key&gt;
      &lt;true/&gt;
    &lt;key&gt;com.apple.security.get-task-allow&lt;/key&gt;
      &lt;true/&gt;
  &lt;/dict&gt;
&lt;/plist&gt;
</code></pre>
<!--kg-card-end: markdown--><p>&#x7136;&#x540E;&#x901A;&#x8FC7;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x66FF;&#x6362;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x7684;&#x7B7E;&#x540D;&#xFF0C;&#x5F00;&#x53D1;&#x8005;&#x8BC1;&#x4E66;&#x540D;&#x9009;&#x62E9;&#x81EA;&#x5DF1;&#x7684;&#x8BC1;&#x4E66;&#x5373;&#x53EF;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>codesign --entitlements entitlements.xml -fs &lt;&#x5F00;&#x53D1;&#x8005;&#x8BC1;&#x4E66;&#x540D;&gt; /Applications/Thunder.app
</code></pre>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-31.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1124" height="90" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-31.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-31.png 1000w, https://lemonlie.com/content/images/2022/07/image-31.png 1124w" sizes="(min-width: 720px) 720px"></figure><p>&#x8FD9;&#x4E2A;&#x5C31;&#x8868;&#x793A;&#x66FF;&#x6362;&#x6210;&#x529F;&#x4E86;&#x3002;&#x7136;&#x540E;&#x518D;&#x8FD0;&#x884C;&#x53D1;&#x73B0;&#x8FD8;&#x662F;&#x4F1A;&#x62A5;&#x9519;&#xFF0C;&#x4F46;&#x662F;&#x73B0;&#x5728;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x542F;&#x52A8;&#x5E94;&#x7528;&#x4E86;&#x3002;</p><p>&#x8FD9;&#x65F6;&#x5019;&#x5728;&#x6211;&#x4EEC;&#x81EA;&#x5DF1;&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#x6253;&#x65AD;&#x70B9;&#xFF0C;&#x53D1;&#x73B0;&#x8FD8;&#x662F;&#x4E0D;&#x4F1A;&#x65AD;&#x4F4F;&#xFF0C;&#x8FD9;&#x662F;&#x56E0;&#x4E3A;&#x5E94;&#x7528;&#x8FD8;&#x6CA1;&#x6709;&#x52A0;&#x8F7D;&#x6211;&#x4EEC;&#x7684;&#x52A8;&#x6001;&#x5E93;&#x3002;&#x53EA;&#x9700;&#x8981;&#x5728;&#x5E94;&#x7528;&#x542F;&#x52A8;&#x4E4B;&#x524D;&#x628A;&#x6211;&#x4EEC;&#x7684;&#x52A8;&#x6001;&#x5E93;&#x63D2;&#x5165;&#x5230;&#x5E94;&#x7528;&#x5373;&#x53EF;&#xFF0C;&#x8FD9;&#x65F6;&#x5019;&#x53C8;&#x9700;&#x8981;&#x7528;&#x5230;insert_dylib&#x4E86;&#x3002;&#x5728;&#x9879;&#x76EE;&#x6839;&#x76EE;&#x5F55;&#x521B;&#x5EFA;&#x4E2A;Other&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x7136;&#x540E;&#x628A;insert_dylib&#x653E;&#x8FDB;&#x53BB;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-32.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1058" height="372" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-32.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-32.png 1000w, https://lemonlie.com/content/images/2022/07/image-32.png 1058w" sizes="(min-width: 720px) 720px"></figure><p>&#x7136;&#x540E;&#x5728;&#x5DE5;&#x7A0B;Build Phases&#x4E2D;&#x521B;&#x5EFA;&#x4E2A;&#x811A;&#x672C;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-33.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1306" height="266" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-33.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-33.png 1000w, https://lemonlie.com/content/images/2022/07/image-33.png 1306w" sizes="(min-width: 720px) 720px"></figure><p>&#x521B;&#x5EFA;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x628A;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#x590D;&#x5236;&#x8FDB;&#x53BB;</p><!--kg-card-begin: markdown--><pre><code>app_name=&quot;Thunder&quot;
framework_name=&quot;libThunderPlugin&quot;
app_bundle_path=&quot;/Applications/${app_name}.app/Contents/MacOS&quot;
app_executable_path=&quot;${app_bundle_path}/${app_name}&quot;
app_executable_backup_path=&quot;${app_executable_path}_backup&quot;
framework_path=&quot;${app_bundle_path}/${framework_name}.framework&quot;
# &#x5907;&#x4EFD;&#x539F;&#x59CB;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;
if [ ! -f &quot;$app_executable_backup_path&quot; ]
then
cp &quot;$app_executable_path&quot; &quot;$app_executable_backup_path&quot;
fi

rm -rf &quot;./Other/Products/Debug/${framework_name}.framework&quot;
cp -r &quot;${BUILT_PRODUCTS_DIR}/${framework_name}.framework&quot; &quot;./Other/Products/Debug/${framework_name}.framework&quot;
cp -r &quot;${BUILT_PRODUCTS_DIR}/${framework_name}.framework&quot; ${app_bundle_path}
./Other/insert_dylib --all-yes &quot;${framework_path}/${framework_name}&quot; &quot;$app_executable_backup_path&quot; &quot;$app_executable_path&quot;

</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x91CC;&#x9762;&#x7684;&#x5185;&#x5BB9;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x5E2E;&#x6211;&#x4EEC;&#x5B8C;&#x6210;&#x4E86;&#x4E0A;&#x9762;&#x6211;&#x4EEC;&#x624B;&#x52A8;&#x63D2;&#x5165;framework&#x7684;&#x64CD;&#x4F5C;&#x3002;&#x4E0A;&#x8FF0;&#x64CD;&#x4F5C;&#x90FD;&#x5B8C;&#x6210;&#x540E;&#x65AD;&#x70B9;&#x8FD8;&#x662F;&#x6CA1;&#x6709;&#x751F;&#x6548;&#x7684;&#xFF0C;&#x662F;&#x56E0;&#x4E3A;&#x8FD8;&#x6CA1;&#x6709;&#x8C03;&#x7528;&#x65B9;&#x6CD5;&#x7684;&#x66FF;&#x6362;&#xFF0C;&#x4E00;&#x822C;&#x7684;&#x8BDD;&#x662F;&#x5728;&#x7C7B; + (void)load&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#x5B9E;&#x73B0;&#x65B9;&#x6CD5;&#x7684;&#x66FF;&#x6362;&#xFF0C;&#x4F46;&#x662F;&#x5BF9;&#x4E8E;framework&#x6765;&#x8BF4;&#xFF0C;&#x8FD8;&#x4F1A;&#x6709;&#x4E00;&#x4E9B;C&#x3001;C++&#x548C;Swift&#x7684;&#x65B9;&#x6CD5;&#x66FF;&#x6362;&#xFF0C;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x662F;&#x6CA1;&#x6709;load&#x65B9;&#x6CD5;&#x7684;&#x3002;&#x4E86;&#x89E3;dyld&#x52A0;&#x8F7D;&#x6D41;&#x7A0B;&#x7684;&#x5E94;&#x8BE5;&#x77E5;&#x9053;&#xFF0C;dyld&#x4F1A;&#x8C03;&#x7528;&#x6BCF;&#x4E2A;framework&#x7684;initialize&#x65B9;&#x6CD5;&#x53BB;&#x521D;&#x59CB;&#x5316;&#x3002;&#x7136;&#x540E;&#x6211;&#x4EEC;&#x5199;&#x5165;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>static void __attribute__((constructor)) initialize(void) {
    [NSObject hookThunder];
}

</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x65F6;&#x5019;&#x518D;&#x8FD0;&#x884C;&#xFF0C;&#x53D1;&#x73B0;&#x662F;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x65AD;&#x4F4F;&#x7684;&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x770B;&#x5230;arg1&#x662F;NSDictionary&#x7C7B;&#x578B;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-34.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1302" height="426" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-34.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-34.png 1000w, https://lemonlie.com/content/images/2022/07/image-34.png 1302w" sizes="(min-width: 720px) 720px"></figure><p>&#x5177;&#x4F53;&#x66F4;&#x6539;&#x54EA;&#x4E9B;&#x6570;&#x636E;&#x53EF;&#x4EE5;&#x8FBE;&#x5230;&#x6211;&#x4EEC;&#x60F3;&#x8981;&#x7684;&#x6548;&#x679C;&#x5C31;&#x9700;&#x8981;&#x81EA;&#x5DF1;&#x4E00;&#x4E2A;&#x4E2A;&#x5C1D;&#x8BD5;&#x4E86;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x591A;&#x8BF4;&#x4E86;&#x3002;</p><p>&#x5230;&#x8FD9;&#x91CC;&#x5C31;&#x4F1A;&#x6709;&#x4EBA;&#x95EE;&#xFF0C;&#x5982;&#x679C;&#x901A;&#x8FC7;&#x641C;&#x7D22;&#x627E;&#x4E0D;&#x5230;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x7684;&#x65B9;&#x6CD5;&#x600E;&#x4E48;&#x529E;&#xFF1F;&#x4E0D;&#x8FC7;&#x786E;&#x5B9E;&#xFF0C;&#x505A;&#x9006;&#x5411;&#x4E0D;&#x662F;&#x6BCF;&#x6B21;&#x90FD;&#x90A3;&#x4E48;&#x597D;&#x8FD0;&#x6C14;&#x7684;&#x3002;&#x5982;&#x679C;&#x8FD9;&#x6837;&#x7684;&#x8BDD;&#x5C31;&#x9700;&#x8981;&#x901A;&#x8FC7;UI&#x627E;&#x6570;&#x636E;&#x4E86;&#x3002;Xcode&#x6709;&#x4E2A;Debug View Hierarchy&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x5982;&#x4E0B;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-35.png" class="kg-image" alt="&#x5982;&#x4F55;&#x4E3A;macOS&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x63D2;&#x4EF6;" loading="lazy" width="1618" height="958" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-35.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-35.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/07/image-35.png 1600w, https://lemonlie.com/content/images/2022/07/image-35.png 1618w" sizes="(min-width: 720px) 720px"></figure><p>&#x611F;&#x5174;&#x8DA3;&#x81EA;&#x5DF1;&#x7814;&#x7A76;&#x5427;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x591A;&#x8BF4;&#x4E86;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[深入分析objc_msgSend尾调用优化]]></title><description><![CDATA[<p>&#x65E0;&#x610F;&#x95F4;&#x770B;&#x5230;&#x4E86;&#x8FD9;&#x7BC7;&#x6587;&#x7AE0; <a href="https://juejin.cn/post/7088893268036943908?ref=lemonlie.com"><strong>iOS objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x8BE6;&#x89E3;</strong></a>&#xFF0C;&#x8BB2;&#x7684;&#x662F;&#x5728;Release&#x6A21;&#x5F0F;&#x4E0B;&#xFF0C;&#x5F53;&#x67D0;&#x51FD;&#x6570;&#x7684;&#x6700;&#x540E;&#x4E00;&#x9879;&#x64CD;&#x4F5C;&#x662F;&#x8C03;&#x7528;&#x53E6;&#x5916;&#x4E00;&#x4E2A;&#x51FD;&#x6570;</p>]]></description><link>https://lemonlie.com/shen-ru-fen-xi-objc_msgsendwei-diao-yong-you-hua/</link><guid isPermaLink="false">65672ee96c00b44e30765795</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Mon, 18 Jul 2022 14:20:26 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1503437313881-503a91226402?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE3fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1503437313881-503a91226402?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE3fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;"><p>&#x65E0;&#x610F;&#x95F4;&#x770B;&#x5230;&#x4E86;&#x8FD9;&#x7BC7;&#x6587;&#x7AE0; <a href="https://juejin.cn/post/7088893268036943908?ref=lemonlie.com"><strong>iOS objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x8BE6;&#x89E3;</strong></a>&#xFF0C;&#x8BB2;&#x7684;&#x662F;&#x5728;Release&#x6A21;&#x5F0F;&#x4E0B;&#xFF0C;&#x5F53;&#x67D0;&#x51FD;&#x6570;&#x7684;&#x6700;&#x540E;&#x4E00;&#x9879;&#x64CD;&#x4F5C;&#x662F;&#x8C03;&#x7528;&#x53E6;&#x5916;&#x4E00;&#x4E2A;&#x51FD;&#x6570;&#xFF0C;&#x7F16;&#x8BD1;&#x5668;&#x4F1A;&#x751F;&#x6210;&#x8C03;&#x8F6C;&#x81F3;&#x53E6;&#x4E00;&#x51FD;&#x6570;&#x6240;&#x9700;&#x7684;&#x6307;&#x4EE4;&#x7801;&#xFF0C;&#x800C;&#x4E14;&#x4E0D;&#x4F1A;&#x5411;&#x8C03;&#x7528;&#x5806;&#x6808;&#x4E2D;&#x63A8;&#x5165;&#x65B0;&#x7684;&#x201C;&#x6808;&#x5E27;&#x201D;&#xFF08;frame stack&#xFF09;&#xFF0C;&#x4EE5;&#x5B9E;&#x73B0;&#x6808;&#x5E27;&#x590D;&#x7528;&#x3002;</p><p>&#x6808;&#x5E27;&#x5C31;&#x662F;&#x4E00;&#x4E2A;&#x51FD;&#x6570;&#x6267;&#x884C;&#x7684;&#x73AF;&#x5883;&#xFF1A;&#x51FD;&#x6570;&#x53C2;&#x6570;&#x3001;&#x51FD;&#x6570;&#x7684;&#x5C40;&#x90E8;&#x53D8;&#x91CF;&#x3001;&#x51FD;&#x6570;&#x6267;&#x884C;&#x5B8C;&#x540E;&#x8FD4;&#x56DE;&#x5230;&#x54EA;&#x91CC;&#x7B49;&#x7B49;&#x3002;&#x6240;&#x4EE5;&#x5728;&#x6BCF;&#x4E00;&#x6B21;&#x51FD;&#x6570;&#x8C03;&#x7528;&#x4E4B;&#x524D;&#xFF0C;&#x9700;&#x8981;&#x4FDD;&#x5B58;&#x4E0B;&#x6267;&#x884C;&#x7684;&#x73AF;&#x5883;&#xFF0C;&#x4EE5;&#x786E;&#x4FDD;&#x6B63;&#x5E38;&#x8FD4;&#x56DE;&#x5230;&#x8C03;&#x7528;&#x4F4D;&#x7F6E;&#x3002;&#x4E0B;&#x9762;&#x662F;- (void)viewDidLoad&#x65B9;&#x6CD5;&#x7684;&#x6C47;&#x7F16;&#x4EE3;&#x7801;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-2.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;" loading="lazy" width="1550" height="484" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-2.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-2.png 1000w, https://lemonlie.com/content/images/2022/07/image-2.png 1550w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#x5728;&#x8C03;&#x7528;[super viewDidLoad]&#x4E4B;&#x524D;&#xFF0C;&#x5148;&#x7533;&#x8BF7;&#x6808;&#x7A7A;&#x95F4;&#xFF0C;&#x7136;&#x540E;&#x4FDD;&#x5B58;x29&#x548C;x30&#x5BC4;&#x5B58;&#x5668;&#x7684;&#x503C;&#xFF0C;&#x8C03;&#x7528;&#x7ED3;&#x675F;&#x540E;&#x6062;&#x590D;&#x5BC4;&#x5B58;&#x5668;&#x7684;&#x503C;&#xFF0C;&#x7136;&#x540E;&#x5E73;&#x6808;&#x3002;x29&#x5BC4;&#x5B58;&#x5668;&#x4E5F;&#x5C31;&#x662F;fp&#x5BC4;&#x5B58;&#x5668;&#xFF0C;&#x4FDD;&#x5B58;&#x6808;&#x5E95;&#x7684;&#x5730;&#x5740;&#x3002;x30&#x5BC4;&#x5B58;&#x5668;&#x4E5F;&#x5C31;&#x662F;lr&#x5BC4;&#x5B58;&#x5668;&#xFF0C;&#x4FDD;&#x5B58;&#x8FD4;&#x56DE;&#x5730;&#x5740;&#x3002;&#x90A3;&#x6808;&#x5E27;&#x590D;&#x7528;&#x53C8;&#x662F;&#x600E;&#x4E48;&#x5B9E;&#x73B0;&#x7684;&#x5462;&#xFF1F;&#x672C;&#x7740;&#x77E5;&#x5176;&#x7136;&#x77E5;&#x5176;&#x6240;&#x4EE5;&#x7136;&#x7684;&#x7CBE;&#x795E;&#xFF0C;&#x6DF1;&#x5165;&#x7814;&#x7A76;&#x4E0B;&#x3002;&#x7528;&#x4E0B;&#x6587;&#x7AE0;&#x4E2D;&#x7684;&#x4F8B;&#x5B50;</p><pre><code>- (NSInteger)func1:(NSInteger)num{
    if (num &gt;= 2000000) {
        return num;
    }
    return [self func1:num + 1];
}
</code></pre>
<p>&#x8FD0;&#x884C;&#x6253;&#x65AD;&#x70B9;&#xFF0C;&#x67E5;&#x770B;&#x6C47;&#x7F16;&#x4EE3;&#x7801;&#x5982;&#x4E0B;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-3.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;" loading="lazy" width="1422" height="378" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-3.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-3.png 1000w, https://lemonlie.com/content/images/2022/07/image-3.png 1422w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x4EE5;&#x53D1;&#x73B0;&#xFF0C;&#x8FD9;&#x91CC;&#x9762;&#x5E76;&#x6CA1;&#x6709;&#x4FDD;&#x5B58;&#x548C;&#x6062;&#x590D;&#x5BC4;&#x5B58;&#x5668;&#x7684;&#x64CD;&#x4F5C;&#xFF0C;&#x4E5F;&#x6CA1;&#x6709;&#x7533;&#x8BF7;&#x6808;&#x7A7A;&#x95F4;&#x3002;&#x5982;&#x679C;&#x4E0D;&#x4FDD;&#x5B58;&#xFF0C;&#x51FD;&#x6570;&#x6267;&#x884C;&#x5B8C;&#x4F1A;&#x8FD4;&#x56DE;&#x54EA;&#x91CC;&#x5462;&#xFF1F;&#x8FD9;&#x91CC;&#x5C31;&#x8981;&#x770B;&#x4E0B;&#xFF0C;fp&#x548C;lr&#x5BC4;&#x5B58;&#x5668;&#x4E86;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-4.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;" loading="lazy" width="1384" height="592" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-4.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-4.png 1000w, https://lemonlie.com/content/images/2022/07/image-4.png 1384w" sizes="(min-width: 720px) 720px"></figure><p>&#x591A;&#x6B21;&#x70B9;&#x7EE7;&#x7EED;&#x6267;&#x884C;&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x8FD9;&#x4E09;&#x4E2A;&#x5BC4;&#x5B58;&#x5668;&#x7684;&#x503C;&#x662F;&#x4E0D;&#x4F1A;&#x53D8;&#x7684;&#x3002;&#x4E5F;&#x5C31;&#x662F;&#x8BF4;&#xFF0C;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7EE7;&#x627F;&#x4E86;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x6267;&#x884C;&#x73AF;&#x5883;&#x3002;&#x8FD9;&#x5C31;&#x5F88;&#x597D;&#x7406;&#x89E3;&#x4E86;&#xFF0C;&#x56E0;&#x4E3A;&#x662F;&#x5C3E;&#x8C03;&#x7528;&#xFF0C;&#x7F16;&#x8BD1;&#x5668;&#x8BA4;&#x4E3A;&#x5DF2;&#x7ECF;&#x6CA1;&#x5FC5;&#x8981;&#x518D;&#x8FD4;&#x56DE;&#x5230;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x4E86;&#xFF0C;&#x5F53;&#x524D;&#x51FD;&#x6570;&#x6267;&#x884C;&#x5B8C;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x5230;&#x6700;&#x7EC8;&#x5730;&#x5740;&#x5C31;&#x53EF;&#x4EE5;&#x4E86;&#x3002;</p><p>&#x6267;&#x884C;&#x73AF;&#x5883;&#x662F;&#x5305;&#x542B;fp&#x548C;sp&#x7684;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x6807;&#x8BC6;&#x7740;&#x6808;&#x7A7A;&#x95F4;&#x7684;&#x8D77;&#x59CB;&#xFF0C;&#x5982;&#x679C;&#x6808;&#x7A7A;&#x95F4;&#x53D1;&#x751F;&#x53D8;&#x5316;&#xFF0C;&#x90A3;&#x4E48;&#x8FD8;&#x4F1A;&#x590D;&#x7528;&#x6808;&#x5E27;&#x5417;&#xFF1F;&#x5199;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;</p><pre><code>- (NSInteger)func1:(NSInteger)num{
    NSObject *obj = [NSObject new];
    if (num &gt;= 2000000) {
        return num;
    }
    return [self func1:num + 1];
}
</code></pre>
<p>&#x7EE7;&#x7EED;&#x8C03;&#x8BD5;&#xFF0C;&#x53D1;&#x73B0;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5E76;&#x6CA1;&#x6709;&#x4F18;&#x5316;&#x3002;&#x5982;&#x56FE;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-5.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;" loading="lazy" width="1284" height="256" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-5.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-5.png 1000w, https://lemonlie.com/content/images/2022/07/image-5.png 1284w" sizes="(min-width: 720px) 720px"></figure><p>&#x4E5F;&#x5C31;&#x662F;&#x8BF4;&#xFF0C;&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x9700;&#x8981;&#x540C;&#x65F6;&#x6EE1;&#x8DB3;&#x6808;&#x7A7A;&#x95F4;&#x6CA1;&#x6709;&#x53D8;&#x5316;&#x3002;</p><p>&#x6587;&#x7AE0;&#x4E2D;&#x63D0;&#x5230;&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x7684;&#x6761;&#x4EF6;&#x6709;&#x4E00;&#x6761;&#x4E3A;&#xFF1A;&#x5C3E;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x4E0D;&#x9700;&#x8981;&#x8BBF;&#x95EE;&#x5F53;&#x524D;&#x6808;&#x5E27;&#x4E2D;&#x7684;&#x53D8;&#x91CF;&#x3002;&#xFF08;&#x53D8;&#x91CF;&#x53EF;&#x4EE5;&#x4F5C;&#x4E3A;&#x5F62;&#x53C2;&#xFF0C;&#x4F46;&#x662F;&#x4E0D;&#x80FD;&#x4F5C;&#x4E3A;&#x5B9E;&#x53C2;&#xFF09;</p><p>&#x5982;&#x679C;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x53C2;&#x6570;&#x6570;&#x91CF;&#x5927;&#x4E8E;&#x5BC4;&#x5B58;&#x5668;&#x6240;&#x80FD;&#x4F20;&#x9012;&#x7684;&#x6570;&#x91CF;&#x65F6;&#xFF0C;&#x662F;&#x9700;&#x8981;&#x901A;&#x8FC7;&#x6808;&#x4F20;&#x9012;&#x7684;&#x3002;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x662F;&#x4E0D;&#x662F;&#x4E5F;&#x4E0D;&#x4F1A;&#x4F18;&#x5316;&#x5462;&#xFF1F;&#x5199;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x9A8C;&#x8BC1;</p><pre><code>- (NSInteger)func1:(NSInteger)num{
    if (num &gt;= 2000000) {
        return num;
    }
    return [self funcA:1 B:2 C:3 D:4 E:5 F:6 G:7 H:8 J:9];
}

- (int)funcA:(int)a B:(int)b C:(int)c D:(int)d E:(int)e F:(int)f G:(int)g H:(int)h J:(int)j{
    int value = a + b + c + d + e + f + g + h + j;
    if (value &gt;= 200000) {
        return value;
    }
    return [self funcA:a + 1 B:b + 1 C:c + 1 D:d + 1 E:e + 1 F:f + 1 G:g + 1 H:h +1 J:j + 1];
}
</code></pre>
<p>&#x5207;&#x6362;&#x5230;&#x6C47;&#x7F16;&#x4E0B;&#x65AD;&#x70B9;&#x5728;objc_msgSend&#x524D;&#xFF0C;&#x53EF;&#x4EE5;&#x53D1;&#x73B0;&#x5F53;&#x53C2;&#x6570;&#x5927;&#x4E8E;9&#x4E2A;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5C31;&#x9700;&#x8981;&#x6808;&#x4F20;&#x9012;&#x4E86;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-8.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;" loading="lazy" width="2000" height="1071" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-8.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-8.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/07/image-8.png 1600w, https://lemonlie.com/content/images/2022/07/image-8.png 2092w" sizes="(min-width: 720px) 720px"></figure><p>&#x7EE7;&#x7EED;&#x8FD0;&#x884C;&#x53EF;&#x4EE5;&#x53D1;&#x73B0;&#xFF0C;&#x8FD9;&#x91CC;funcA&#x5E76;&#x6CA1;&#x6709;&#x590D;&#x7528;func1&#x7684;&#x6808;&#x5E27;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x6CA1;&#x6709;&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x3002;&#x800C;funcA&#x51FD;&#x6570;&#x7684;&#x6808;&#x5E27;&#x88AB;&#x590D;&#x7528;&#x4E86;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-9.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;" loading="lazy" width="2000" height="444" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-9.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-9.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/07/image-9.png 1600w, https://lemonlie.com/content/images/2022/07/image-9.png 2162w" sizes="(min-width: 720px) 720px"></figure><p>&#x901A;&#x8FC7;&#x4EE5;&#x4E0A;&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x5F53;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x6808;&#x7A7A;&#x95F4;&#x5927;&#x4E8E;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x6808;&#x7A7A;&#x95F4;&#x65F6;&#xFF0C;&#x56E0;&#x4E3A;&#x9700;&#x8981;&#x5F00;&#x8F9F;&#x65B0;&#x7684;&#x7A7A;&#x95F4;&#xFF0C;fp&#x548C;sp&#x662F;&#x9700;&#x8981;&#x53D8;&#x5316;&#x7684;&#xFF0C;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#x662F;&#x4E0D;&#x4F1A;&#x4F18;&#x5316;&#x7684;&#x3002;&#x5F53;&#x76F8;&#x7B49;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4E5F;&#x662F;&#x53EF;&#x4EE5;&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x7684;&#x3002;&#x90A3;&#x4F1A;&#x6709;&#x4EBA;&#x95EE;&#xFF0C;&#x4E3A;&#x4EC0;&#x4E48;&#x4EE5;&#x4E0B;&#x60C5;&#x51B5;&#x6CA1;&#x6709;&#x590D;&#x7528;&#x6808;&#x5E27;&#x5462;&#xFF1F;</p><pre><code>- (NSInteger)func1:(NSInteger)num{
    NSObject *obj = [NSObject new];
    if (num &gt;= 2000000) {
        return num;
    }
    return [self func1:num + 1];
}
</code></pre>
<p>&#x56E0;&#x4E3A;&#x5BF9;&#x8C61;&#x662F;&#x6D89;&#x53CA;&#x5230;&#x751F;&#x547D;&#x5468;&#x671F;&#x7684;&#xFF0C;&#x5728;&#x8C03;&#x7528;&#x65B9;&#x6CD5;&#x4E4B;&#x524D;&#xFF0C;&#x5BF9;&#x8C61;&#x8FD8;&#x6CA1;&#x6709;&#x91CA;&#x653E;&#xFF0C;&#x6808;&#x7A7A;&#x95F4;&#x8FD8;&#x662F;&#x4F7F;&#x7528;&#x72B6;&#x6001;&#xFF0C;&#x6240;&#x4EE5;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x65E0;&#x6CD5;&#x590D;&#x7528;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x6808;&#x7A7A;&#x95F4;&#x3002;</p><p>&#x65E2;&#x7136;&#x6808;&#x7A7A;&#x95F4;&#x76F8;&#x7B49;&#x662F;&#x53EF;&#x4EE5;&#x590D;&#x7528;&#x7684;&#xFF0C;&#x90A3;&#x4E48;&#x5F53;&#x5C0F;&#x4E8E;&#x7684;&#x65F6;&#x5019;&#x4E00;&#x5B9A;&#x4E5F;&#x662F;&#x53EF;&#x4EE5;&#x7684;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x8D34;&#x4EE3;&#x7801;&#x4E86;&#x3002;&#x6709;&#x5174;&#x8DA3;&#x7684;&#x53EF;&#x4EE5;&#x81EA;&#x5DF1;&#x9A8C;&#x8BC1;&#x4E0B;&#x3002;</p><p>&#x6808;&#x5E27;&#x590D;&#x7528;&#x53D6;&#x51B3;&#x4E8E;sp&#x3001;fp&#x548C;lr&#x5BC4;&#x5B58;&#x5668;&#xFF0C;&#x90A3;&#x4E48;&#x4EE5;&#x4E0B;&#x60C5;&#x51B5;&#x4E5F;&#x662F;&#x53EF;&#x4EE5;&#x7684;</p><pre><code>- (NSInteger)func1:(NSInteger)num{
    if (num &gt;= 2000000) {
        return num;
    }
    num = [self func2:num];
    return num;
}
- (NSInteger)func2:(NSInteger)num{
    return num;
}
</code></pre>
<p>&#x6BD5;&#x7ADF;&#x5BF9;&#x4E8E;&#x7F16;&#x8BD1;&#x5668;&#x6765;&#x8BF4;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x51FD;&#x6570;&#x548C;&#x8FD4;&#x56DE;&#x51FD;&#x6570;&#x7684;&#x8FD4;&#x56DE;&#x503C;&#x662F;&#x4E00;&#x6837;&#x7684;&#xFF0C;&#x770B;&#x6C47;&#x7F16;&#x786E;&#x5B9E;&#x662F;&#x8FD9;&#x6837;&#x7684;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image-10.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;objc_msgSend&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;" loading="lazy" width="2000" height="425" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image-10.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image-10.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/07/image-10.png 1600w, https://lemonlie.com/content/images/size/w2400/2022/07/image-10.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>&#x90A3;&#x4E48;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E5F;&#x662F;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0;&#x6808;&#x590D;&#x7528;&#xFF0C;&#x800C;&#x5982;&#x679C;&#x8FD4;&#x56DE;&#x503C;&#x4E0D;&#x5355;&#x7EAF;&#x662F;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x8FD4;&#x56DE;&#x503C;&#xFF0C;&#x5F53;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x540E;&#x8FD8;&#x9700;&#x8981;&#x505A;&#x4E00;&#x4E9B;&#x9700;&#x8981;&#x5BC4;&#x5B58;&#x5668;&#x76F8;&#x5173;&#x7684;&#x64CD;&#x4F5C;&#x7684;&#x8BDD;&#xFF0C;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x662F;&#x9700;&#x8981;&#x4FDD;&#x5B58;&#x4E0A;&#x4E0B;&#x6587;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x4E0D;&#x80FD;&#x5B9E;&#x73B0;&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x3002;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x505A;&#x6D4B;&#x8BD5;&#x4E86;&#x3002;</p><p>&#x7EFC;&#x4E0A;&#x5C3E;&#x8C03;&#x7528;&#x4F18;&#x5316;&#x6761;&#x4EF6;&#x5982;&#x4E0B;&#xFF1A;</p><p>1&#x3001;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x503C;&#x4E3A;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x8FD4;&#x56DE;&#x503C;&#x6216;&#x8005;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x672C;&#x4F53;&#x3002;</p><p>2&#x3001;&#x88AB;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x7684;&#x6808;&#x7A7A;&#x95F4;&#x4E0D;&#x80FD;&#x5927;&#x4E8E;&#x8C03;&#x7528;&#x51FD;&#x6570;&#x6240;&#x7533;&#x8BF7;&#x7684;&#x6808;&#x7A7A;&#x95F4;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[深入分析弱引用（__weak）]]></title><description><![CDATA[<p>__weak &#x5728;&#x5F00;&#x53D1;&#x4E2D;&#x7ECF;&#x5E38;&#x7528;&#x5230;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x4E3A;&#x4E86;&#x89E3;&#x51B3;&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x4E2D;&#x7684;&#x5FAA;&#x73AF;&#x5F15;&#x7528;&#x3002;__weak&#x4FEE;&#x9970;&#x7684;&#x6307;&#x9488;&#x7279;&#x6027;&#x662F;&#x5176;&#x6307;&#x5411;&#x7684;&#x5BF9;&#x8C61;&#x9500;&#x6BC1;&#x540E;&#xFF0C;&#x4F1A;&#x81EA;&#x52A8;</p>]]></description><link>https://lemonlie.com/shen-ru-fen-xi-weak/</link><guid isPermaLink="false">65672ee96c00b44e30765793</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Wed, 06 Jul 2022 15:07:30 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1609008661074-0fe916c4e370?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE2fHx3ZWFrfGVufDB8fHx8MTY1NzExOTk5MA&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1609008661074-0fe916c4e370?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE2fHx3ZWFrfGVufDB8fHx8MTY1NzExOTk5MA&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;&#x5F31;&#x5F15;&#x7528;&#xFF08;__weak&#xFF09;"><p>__weak &#x5728;&#x5F00;&#x53D1;&#x4E2D;&#x7ECF;&#x5E38;&#x7528;&#x5230;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x4E3A;&#x4E86;&#x89E3;&#x51B3;&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x4E2D;&#x7684;&#x5FAA;&#x73AF;&#x5F15;&#x7528;&#x3002;__weak&#x4FEE;&#x9970;&#x7684;&#x6307;&#x9488;&#x7279;&#x6027;&#x662F;&#x5176;&#x6307;&#x5411;&#x7684;&#x5BF9;&#x8C61;&#x9500;&#x6BC1;&#x540E;&#xFF0C;&#x4F1A;&#x81EA;&#x52A8;&#x7F6E;&#x4E3A; nil&#x3002;</p><p>&#x7528;&#x5230;__weak&#x57FA;&#x672C;&#x4E0A;&#x5206;&#x4E24;&#x79CD;&#x60C5;&#x51B5;&#xFF0C;&#x4E00;&#x79CD;&#x662F;&#x5148;&#x58F0;&#x660E;&#x518D;&#x8D4B;&#x503C;&#xFF08;@property (weak)&#x4E5F;&#x662F;&#x8FD9;&#x79CD;&#xFF09;&#xFF0C;&#x53E6;&#x4E00;&#x79CD;&#x662F;&#x58F0;&#x660E;&#x7684;&#x65F6;&#x5019;&#x8D4B;&#x503C;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>NSObject *obj = [NSObject new];
__weak id weak;
weak = obj;
__weak id weak1 = obj;
</code></pre>
<!--kg-card-end: markdown--><p>&#x65B0;&#x5EFA;&#x4E2A;&#x9879;&#x76EE;&#xFF0C;&#x5728;&#x9879;&#x76EE;&#x4E2D;&#x5199;&#x5165;&#x4EE5;&#x4E0A;&#x4EE3;&#x7801;&#xFF0C;&#x7136;&#x540E;&#x518D;&#x7EC8;&#x7AEF;&#x8F93;&#x5165;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x7F16;&#x8BD1;&#x6210;C++&#x6E90;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 &quot;&#x66FF;&#x6362;&#x4E3A;&#x5199;&#x4EE3;&#x7801;&#x7684;&#x6587;&#x4EF6;&quot;
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x5F97;&#x5230;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#xFF0C;&#x53D1;&#x73B0;__weak &#x5BF9;&#x5E94;&#x7684;&#x7C7B;&#x578B;&#x5C5E;&#x6027;&#x90FD;&#x4E3A;__attribute((objc_ownership(weak)))&#xFF0C;&#x4EE3;&#x8868;&#x4EE5;weak&#x5F31;&#x5F15;&#x2F64;&#x7684;&#x2F45;&#x5F0F;&#x7BA1;&#x7406;&#x5BF9;&#x8C61;&#x6240;&#x6709;&#x6743;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>__attribute__((objc_ownership(weak))) id weak;
weak = obj;
__attribute__((objc_ownership(weak))) id week2 = obj;
</code></pre>
<!--kg-card-end: markdown--><p>&#x7136;&#x540E;&#x518D;&#x5728;&#x6E90;&#x7801;&#x4E2D;&#x6253;&#x65AD;&#x70B9;&#xFF0C;&#x8FD0;&#x884C;&#x8FDB;&#x5165;&#x8C03;&#x8BD5;&#x6A21;&#x5F0F;&#x3002;&#x518D;&#x901A;&#x8FC7;Xcode&#x83DC;&#x5355;Debug-&gt;Debug Workflow-&gt;Always Show Disassembly &#x8FDB;&#x5165;&#x5230;&#x6C47;&#x7F16;&#x6A21;&#x5F0F;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/Screen-Shot-2022-07-04-at-18.43.35.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;&#x5F31;&#x5F15;&#x7528;&#xFF08;__weak&#xFF09;" loading="lazy" width="1402" height="810" srcset="https://lemonlie.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-04-at-18.43.35.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-04-at-18.43.35.png 1000w, https://lemonlie.com/content/images/2022/07/Screen-Shot-2022-07-04-at-18.43.35.png 1402w" sizes="(min-width: 720px) 720px"></figure><p>&#x67E5;&#x770B;&#x6C47;&#x7F16;&#x3002;&#x5982;&#x4E0B;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/Screen-Shot-2022-07-04-at-18.49.33.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;&#x5F31;&#x5F15;&#x7528;&#xFF08;__weak&#xFF09;" loading="lazy" width="1322" height="526" srcset="https://lemonlie.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-04-at-18.49.33.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-04-at-18.49.33.png 1000w, https://lemonlie.com/content/images/2022/07/Screen-Shot-2022-07-04-at-18.49.33.png 1322w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x5148;&#x58F0;&#x660E;&#x540E;&#x8D4B;&#x503C;&#x8C03;&#x7528;&#x7684;&#x662F;objc_storeWeak&#x3002;&#x58F0;&#x660E;&#x7684;&#x65F6;&#x5019;&#x8D4B;&#x503C;&#xFF0C;&#x8C03;&#x7528;&#x7684;&#x662F;objc_initWeak&#x3002;&#x4E3A;&#x4EC0;&#x4E48;&#x540C;&#x6837;&#x662F;weak&#x6307;&#x9488;&#xFF0C;&#x5B9E;&#x73B0;&#x903B;&#x8F91;&#x5374;&#x4E0D;&#x4E00;&#x6837;&#x5462;&#x3002;</p><p>&#x5728;objc&#x6E90;&#x7801;&#x4E2D;&#x627E;&#x5230;&#x8FD9;&#x4E24;&#x4E2A;&#x65B9;&#x6CD5;&#x7684;&#x6E90;&#x7801;&#x3002;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>id objc_storeWeak(id *location, id newObj)
{
    return storeWeak&lt;DoHaveOld, DoHaveNew, DoCrashIfDeallocating&gt;
        (location, (objc_object *)newObj);
}

id objc_initWeak(id *location, id newObj)
{
    if (!newObj) {
        *location = nil;
        return nil;
    }

    return storeWeak&lt;DontHaveOld, DoHaveNew, DoCrashIfDeallocating&gt;
        (location, (objc_object*)newObj);
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x552F;&#x4E00;&#x4E0D;&#x540C;&#x7684;&#x5730;&#x65B9;&#x662F;&#xFF0C;&#x5F53;&#x5BF9;&#x8C61;&#x4E0D;&#x5B58;&#x5728;&#x65F6;&#xFF0C;&#x628A;&#x6307;&#x9488;&#x8BBE;&#x7F6E;&#x4E3A;nil&#xFF0C;&#x53EF;&#x4EE5;&#x9632;&#x6B62;&#x574F;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x3002;&#x53EF;&#x4EE5;&#x770B;&#x51FA;location&#x5B58;&#x50A8;&#x7740;weak&#x6307;&#x9488;&#x7684;&#x5730;&#x5740;&#x3002;&#x800C;&#x7B2C;&#x4E00;&#x79CD;&#x6CA1;&#x6709;&#x8FD9;&#x4E2A;&#x64CD;&#x4F5C;&#x7684;&#x539F;&#x56E0;&#x662F;&#x7F16;&#x8BD1;&#x5668;&#x7B2C;&#x4E00;&#x6B21;&#x4F7F;&#x7528;&#x8FD9;&#x4E2A;&#x6307;&#x9488;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5DF2;&#x7ECF;&#x505A;&#x4E86;&#x8FD9;&#x4E2A;&#x64CD;&#x4F5C;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/07/image.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x5206;&#x6790;&#x5F31;&#x5F15;&#x7528;&#xFF08;__weak&#xFF09;" loading="lazy" width="1370" height="238" srcset="https://lemonlie.com/content/images/size/w600/2022/07/image.png 600w, https://lemonlie.com/content/images/size/w1000/2022/07/image.png 1000w, https://lemonlie.com/content/images/2022/07/image.png 1370w" sizes="(min-width: 720px) 720px"></figure><p>&#x7136;&#x540E;&#x770B;&#x540E;&#x9762;&#x8C03;&#x7528;&#x4E86;&#x4E24;&#x6B21;objc_destroyWeak&#xFF0C;&#x8FD9;&#x662F;&#x56E0;&#x4E3A;&#x79BB;&#x5F00;&#x4E86;&#x5C40;&#x90E8;&#x53D8;&#x91CF;&#x7684;&#x8303;&#x56F4;&#x4E86;&#xFF0C;&#x6BCF;&#x4E00;&#x4E2A;&#x5F31;&#x6307;&#x9488;&#x90FD;&#x9700;&#x8981;&#x6709;&#x4E00;&#x6B21;&#x8C03;&#x7528;&#x3002;&#x4EE3;&#x7801;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>void objc_destroyWeak(id *location)
{
    (void)storeWeak&lt;DoHaveOld, DontHaveNew, DontCrashIfDeallocating&gt;
        (location, nil);
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8FD9;&#x4E09;&#x4E2A;&#x65B9;&#x6CD5;&#x90FD;&#x8C03;&#x7528;&#x4E86;storeWeak&#x65B9;&#x6CD5;&#xFF0C;&#x67E5;&#x770B;&#x6E90;&#x7801;,&#x51FD;&#x6570;&#x7684;&#x5B9E;&#x73B0;&#x592A;&#x957F;&#xFF0C;&#x8FD9;&#x91CC;&#x5206;&#x6BB5;&#x5206;&#x6790;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>// Update a weak variable.
// If HaveOld is true, the variable has an existing value 
//   that needs to be cleaned up. This value might be nil.
// If HaveNew is true, there is a new value that needs to be 
//   assigned into the variable. This value might be nil.
// If CrashIfDeallocating is true, the process is halted if newObj is 
//   deallocating or newObj&apos;s class does not support weak references. 
//   If CrashIfDeallocating is false, nil is stored instead.
enum CrashIfDeallocating {
    DontCrashIfDeallocating = false, DoCrashIfDeallocating = true
};
template &lt;HaveOld haveOld, HaveNew haveNew,
          enum CrashIfDeallocating crashIfDeallocating&gt;
static id 
storeWeak(id *location, objc_object *newObj)
{
    ASSERT(haveOld  ||  haveNew);
    if (!haveNew) ASSERT(newObj == nil);

    Class previouslyInitializedClass = nil;
    id oldObj;
    SideTable *oldTable;
    SideTable *newTable;
</code></pre>
<!--kg-card-end: markdown--><p>&#x51FD;&#x6570;&#x524D;&#x9762;&#x7684;&#x6CE8;&#x91CA;&#xFF0C;&#x8868;&#x9762;&#x4E86;&#x6A21;&#x677F;&#x4E2D;&#x4E09;&#x4E2A;&#x53C2;&#x6570;&#x7684;&#x4F5C;&#x7528;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x505A;&#x7FFB;&#x8BD1;&#x4E86;&#x3002;&#x51FD;&#x6570;&#x5F00;&#x59CB;&#x7684;&#x8FD9;&#x90E8;&#x5206;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x53D8;&#x91CF;&#x58F0;&#x660E;&#xFF0C;&#x8FD9;&#x91CC;&#x4E3B;&#x8981;&#x6CE8;&#x610F;&#x4E0B;SideTable&#x7C7B;&#x578B;&#x3002;&#x67E5;&#x4EE3;&#x7801;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x7ED3;&#x6784;&#x4F53;&#x5B9A;&#x4E49;&#x5982;&#x4E0B;&#xFF08;&#x7701;&#x7565;&#x4E86;&#x7ED3;&#x6784;&#x4F53;&#x51FD;&#x6570;&#xFF09;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>struct SideTable {
    spinlock_t slock;
    RefcountMap refcnts;
    weak_table_t weak_table;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5176;&#x4E2D; slock &#x662F;&#x4E00;&#x4E2A;&#x81EA;&#x65CB;&#x9501;&#xFF0C;&#x5BF9; SideTable &#x5B9E;&#x4F8B;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#x65F6;&#x7528;&#x6765;&#x52A0;&#x9501;&#x3002;refcnts&#x662F;&#x5F53;&#x5BF9;&#x8C61;&#x7684;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#x5927;&#x4E8E;isa&#x6307;&#x9488;&#x6240;&#x80FD;&#x5B58;&#x50A8;&#x7684;&#x6570;&#x503C;&#x65F6;&#xFF0C;&#x5B58;&#x653E;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#x7684;&#x5730;&#x65B9;&#x3002;weak_table &#x5219;&#x662F;&#x5B58;&#x653E;&#x5F31;&#x5F15;&#x7528;&#x6307;&#x9488;&#x7684;&#x5730;&#x65B9;&#xFF08;&#x540E;&#x9762;&#x5C06;&#x8BE6;&#x7EC6;&#x5206;&#x6790; weak_table_t&#xFF09;&#x3002;</p><p>&#x7EE7;&#x7EED;&#x770B;storeWeak&#x51FD;&#x6570;</p><!--kg-card-begin: markdown--><pre><code>    // Acquire locks for old and new values.
    // Order by lock address to prevent lock ordering problems. 
    // Retry if the old value changes underneath us.
 retry:
    if (haveOld) {
        oldObj = *location;
        oldTable = &amp;SideTables()[oldObj];
    } else {
        oldTable = nil;
    }
    if (haveNew) {
        newTable = &amp;SideTables()[newObj];
    } else {
        newTable = nil;
    }

    SideTable::lockTwo&lt;haveOld, haveNew&gt;(oldTable, newTable);

    if (haveOld  &amp;&amp;  *location != oldObj) {
        SideTable::unlockTwo&lt;haveOld, haveNew&gt;(oldTable, newTable);
        goto retry;
    }
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x4E00;&#x6BB5;&#x662F;&#x83B7;&#x53D6;oldOb&#xFF0C;&#x4EE5;&#x53CA;&#x4ECE;SideTables&#x91CC;&#x9762;&#x5206;&#x522B;&#x901A;&#x8FC7;oldObj&#x548C;newObj&#x7684;&#x5730;&#x5740;&#x4F5C;&#x4E3A;key&#x83B7;&#x53D6;&#x5230;&#x4E86;oldTable&#x548C;newTable&#xFF0C;&#x7136;&#x540E;&#x4E0A;&#x9501;&#x3002;</p><p>SideTables&#x8FD4;&#x56DE;&#x7684;&#x662F;StripedMap&lt;SideTable&gt;&#x7C7B;&#x578B;&#x7684;&#x54C8;&#x5E0C;&#x8868;&#xFF0C;&#x8868;&#x7684;&#x957F;&#x5EA6;&#x5728;iPhone&#x4E0A;&#x662F;8&#xFF0C;&#x6A21;&#x62DF;&#x5668;&#x548C;macOS&#x662F;64&#xFF0C;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>class StripedMap {
#if TARGET_OS_IPHONE &amp;&amp; !TARGET_OS_SIMULATOR
    enum { StripeCount = 8 };
#else
    enum { StripeCount = 64 };
#endif

    struct PaddedT {
        T value alignas(CacheLineSize);
    };

    PaddedT array[StripeCount];

    static unsigned int indexForPointer(const void *p) {
        uintptr_t addr = reinterpret_cast&lt;uintptr_t&gt;(p);
        return ((addr &gt;&gt; 4) ^ (addr &gt;&gt; 9)) % StripeCount;
    }
    //&#x7701;&#x7565;&#x4E0B;&#x9762;&#x5185;&#x5BB9;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x7EE7;&#x7EED;storeWeak&#x51FD;&#x6570;</p><!--kg-card-begin: markdown--><pre><code>// Prevent a deadlock between the weak reference machinery
    // and the +initialize machinery by ensuring that no 
    // weakly-referenced object has an un-+initialized isa.
    if (haveNew  &amp;&amp;  newObj) {
        Class cls = newObj-&gt;getIsa();
        if (cls != previouslyInitializedClass  &amp;&amp;  
            !((objc_class *)cls)-&gt;isInitialized()) 
        {
            SideTable::unlockTwo&lt;haveOld, haveNew&gt;(oldTable, newTable);
            class_initialize(cls, (id)newObj);

            // If this class is finished with +initialize then we&apos;re good.
            // If this class is still running +initialize on this thread 
            // (i.e. +initialize called storeWeak on an instance of itself)
            // then we may proceed but it will appear initializing and 
            // not yet initialized to the check above.
            // Instead set previouslyInitializedClass to recognize it on retry.
            previouslyInitializedClass = cls;

            goto retry;
        }
    }
</code></pre>
<!--kg-card-end: markdown--><p>&#x770B;&#x6CE8;&#x91CA;&#x53EF;&#x4EE5;&#x5F97;&#x51FA;&#xFF0C;&#x8FD9;&#x91CC;&#x662F;&#x786E;&#x4FDD;&#x5BF9;&#x8C61;&#x7684;&#x7C7B;&#x5DF2;&#x7ECF;&#x5B8C;&#x6210;+initialize&#x6D41;&#x7A0B;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>    // Clean up old value, if any.
    if (haveOld) {
        weak_unregister_no_lock(&amp;oldTable-&gt;weak_table, oldObj, location);
    }

    // Assign new value, if any.
    if (haveNew) {
        newObj = (objc_object *)
            weak_register_no_lock(&amp;newTable-&gt;weak_table, (id)newObj, location, 
                                  crashIfDeallocating ? CrashIfDeallocating : ReturnNilIfDeallocating);
        // weak_register_no_lock returns nil if weak store should be rejected

        // Set is-weakly-referenced bit in refcount table.
        if (!_objc_isTaggedPointerOrNil(newObj)) {
            newObj-&gt;setWeaklyReferenced_nolock();
        }

        // Do not set *location anywhere else. That would introduce a race.
        *location = (id)newObj;
    }
    else {
        // No new value. The storage is not changed.
    }
    
    SideTable::unlockTwo&lt;haveOld, haveNew&gt;(oldTable, newTable);

    callSetWeaklyReferenced((id)newObj);

    return (id)newObj;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5982;&#x679C;&#x8FD9;&#x4E2A;&#x5F31;&#x6307;&#x9488;&#x672C;&#x8EAB;&#x6307;&#x5411;&#x65E7;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x5148;&#x901A;&#x8FC7;weak_unregister_no_lock&#x65B9;&#x6CD5;&#xFF0C;&#x5176;&#x4ECE; oldTable &#x7684; weak_table &#x4E2D;&#x79FB;&#x9664;&#x3002;&#x5982;&#x679C;&#x6709;&#x65B0;&#x7684;&#x503C;&#xFF0C;&#x5219;&#x4F7F;&#x7528; weak_register_no_lock &#x65B9;&#x6CD5;&#x5C06;&#x5176;&#x6CE8;&#x518C;&#x5230; newTable &#x7684; weak_table &#x4E2D;&#xFF0C;&#x5E76;&#x4F7F;&#x7528; setWeaklyReferenced_nolock &#x51FD;&#x6570;&#x5C06;&#x5BF9;&#x8C61;&#x6807;&#x8BB0;&#x4E3A;&#x88AB;&#x5F31;&#x5F15;&#x7528;&#x8FC7;&#x3002;</p><p>&#x5230;&#x8FD9;&#x91CC;&#xFF0C;&#x5BF9;storeWeak&#x5927;&#x6982;&#x6D41;&#x7A0B;&#x5DF2;&#x7ECF;&#x5206;&#x6790;&#x5B8C;&#x6210; &#xFF0C;&#x5176;&#x91CD;&#x70B9;&#x5C31;&#x5728; weak_register_no_lock &#x548C; weak_unregister_no_lock &#x51FD;&#x6570;&#x4E0A;&#x3002;&#x8FD9;&#x4E24;&#x4E2A;&#x51FD;&#x6570;&#x90FD;&#x7528;&#x5230;&#x4E86;weak_table&#xFF0C;&#x5148;&#x770B;&#x4E0B;weak_table_t&#x5B9A;&#x4E49;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>/**
 * The global weak references table. Stores object ids as keys,
 * and weak_entry_t structs as their values.
 */
struct weak_table_t {
    weak_entry_t *weak_entries; //weak_entry_t&#x7684;&#x6570;&#x7EC4;
    size_t    num_entries; //&#x6570;&#x7EC4;&#x4E2D;weak_entry_t&#x7684;&#x6570;&#x91CF;
    uintptr_t mask;  //&#x54C8;&#x5E0C;&#x540E;&#x7684;&#x503C;&#x53D6;&#x4F59;&#x7B97;&#x7D22;&#x5F15;
    uintptr_t max_hash_displacement; //&#x54C8;&#x5E0C;&#x78B0;&#x649E;&#x540E;&#x6700;&#x5927;&#x7684;&#x4F4D;&#x79FB;&#x503C;
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x518D;&#x770B;&#x4E0B;weak_entry_t&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#xFF08;&#x7701;&#x7565;&#x7ED3;&#x6784;&#x4F53;&#x65B9;&#x6CD5;&#xFF09;</p><!--kg-card-begin: markdown--><pre><code>struct weak_entry_t {
    DisguisedPtr&lt;objc_object&gt; referent;
    union {
        struct {
            weak_referrer_t *referrers;
            uintptr_t        out_of_line_ness : 2;
            uintptr_t        num_refs : PTR_MINUS_2;
            uintptr_t        mask;
            uintptr_t        max_hash_displacement;
        };
        struct {
            // out_of_line_ness field is low bits of inline_referrers[1]
            weak_referrer_t  inline_referrers[WEAK_INLINE_COUNT];
        };
    };
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x7B2C;&#x4E00;&#x4E2A;DisguisedPtr&lt;objc_object&gt;&#x5176;&#x5B9E;&#x5C31;&#x662F; objc_object*&#xFF0C;DisguisedPtr&#x662F;&#x4E3A;&#x4E86;&#x662F;&#x4E3A;&#x4E86;&#x8EB2;&#x8FC7;&#x5185;&#x5B58;&#x6CC4;&#x6F0F;&#x5DE5;&#x5177;&#x7684;&#x68C0;&#x67E5;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>// DisguisedPtr&lt;T&gt; acts like pointer type T*, except the 
// stored value is disguised to hide it from tools like `leaks`.
</code></pre>
<!--kg-card-end: markdown--><p>&#x7B2C;&#x4E8C;&#x4E2A;&#x662F;&#x4E24;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x7684;&#x8054;&#x5408;&#x4F53;&#xFF0C;&#x5148;&#x5206;&#x6790;&#x7B2C;&#x4E00;&#x79CD;&#x3002;</p><p>referrers&#x662F;&#x4E00;&#x4E2A;&#x6307;&#x5411;weak_referrer_t &#x7684;&#x6570;&#x7EC4;&#x6307;&#x9488;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;objc_object *&#x7684;&#x6570;&#x7EC4;&#x6307;&#x9488;</p><!--kg-card-begin: markdown--><pre><code>typedef DisguisedPtr&lt;objc_object *&gt; weak_referrer_t;
</code></pre>
<!--kg-card-end: markdown--><p>out_of_line_ness&#x5360;&#x7528;2 bit &#x6807;&#x8BB0;&#x4F4D;&#xFF0C;&#x7528;&#x6765;&#x786E;&#x5B9A;&#x8054;&#x5408;&#x91CC;&#x7684;&#x5185;&#x5B58;&#x662F;&#x7B2C;&#x4E00;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x8FD8;&#x662F;&#x7B2C;&#x4E8C;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#xFF1B;</p><p>num_refs&#xFF1A;PTR_MINUS_2 &#x662F;&#x5B57;&#x8282;&#x957F;&#x5EA6;&#x51CF;&#x53BB; 2 &#x4F4D;&#xFF0C;&#x548C; out_of_line_ness &#x4E00;&#x8D77;&#x7EC4;&#x6210;&#x4E00;&#x4E2A;&#x5B57;&#x8282;&#xFF0C;&#x7528;&#x6765;&#x5B58;&#x50A8; referrers &#x7684;&#x5927;&#x5C0F;&#xFF1B;</p><p>mask &#x548C; max_hash_displacement&#x505A;&#x54C8;&#x5E0C;&#x8868;&#x7528;&#x5230;&#x7684;&#x4E1C;&#x897F;&#x3002;</p><p>&#x7136;&#x540E;&#x770B;&#x7B2C;&#x4E8C;&#x79CD;&#xFF0C;inline_referrers&#x662F;&#x4E00;&#x4E2A;&#x957F;&#x5EA6;&#x4E3A;WEAK_INLINE_COUNT&#xFF08;4&#xFF09;&#x7684;&#x6570;&#x7EC4;&#x3002;</p><p>&#x901A;&#x8FC7;&#x641C;&#x7D22;&#x4EE3;&#x7801;&#x53EF;&#x4EE5;&#x627E;&#x5230;append_referrer&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#x533A;&#x5206;&#x4E24;&#x79CD;&#x7ED3;&#x679C;&#x7684;&#x5B58;&#x5728;&#x65F6;&#x673A;</p><!--kg-card-begin: markdown--><pre><code>if (! entry-&gt;out_of_line()) {
        // Try to insert inline.
        for (size_t i = 0; i &lt; WEAK_INLINE_COUNT; i++) {
            if (entry-&gt;inline_referrers[i] == nil) {
                entry-&gt;inline_referrers[i] = new_referrer;
                return;
            }
        }

        // Couldn&apos;t insert inline. Allocate out of line.
        weak_referrer_t *new_referrers = (weak_referrer_t *)
            calloc(WEAK_INLINE_COUNT, sizeof(weak_referrer_t));
        // This constructed table is invalid, but grow_refs_and_insert
        // will fix it and rehash it.
        for (size_t i = 0; i &lt; WEAK_INLINE_COUNT; i++) {
            new_referrers[i] = entry-&gt;inline_referrers[i];
        }
        entry-&gt;referrers = new_referrers;
        entry-&gt;num_refs = WEAK_INLINE_COUNT;
        entry-&gt;out_of_line_ness = REFERRERS_OUT_OF_LINE;
        entry-&gt;mask = WEAK_INLINE_COUNT-1;
        entry-&gt;max_hash_displacement = 0;
    }

</code></pre>
<!--kg-card-end: markdown--><p>&#x5F53;weak_referrer_t&#x7684;&#x6570;&#x91CF;&#x5927;&#x4E8E;4&#x4E2A;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x7528;&#x54C8;&#x5E0C;&#x8868;&#x5B58;&#x50A8;&#xFF0C;&#x53CD;&#x4E4B;&#x6570;&#x7EC4;&#x5B58;&#x50A8;&#x3002;</p><p>&#x73B0;&#x5728;&#x56DE;&#x5230;weak_register_no_lock&#x65B9;&#x6CD5;&#xFF0C;&#x53BB;&#x6389;&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x76F8;&#x5173;&#x5185;&#x5BB9;&#x4EE3;&#x7801;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>id weak_register_no_lock(weak_table_t *weak_table, id referent_id, 
                      id *referrer_id, WeakRegisterDeallocatingOptions deallocatingOptions)
{
    objc_object *referent = (objc_object *)referent_id;
    objc_object **referrer = (objc_object **)referrer_id;

    if (_objc_isTaggedPointerOrNil(referent)) return referent_id;

    // now remember it and where it is being stored
    weak_entry_t *entry;
    if ((entry = weak_entry_for_referent(weak_table, referent))) {
        append_referrer(entry, referrer);
    } 
    else {
        weak_entry_t new_entry(referent, referrer);
        weak_grow_maybe(weak_table);
        weak_entry_insert(weak_table, &amp;new_entry);
    }

    // Do not set *referrer. objc_storeWeak() requires that the 
    // value not change.

    return referent_id;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x9996;&#x5148;&#x83B7;&#x53D6;referent&#x548C;referrers&#xFF0C;referent &#x662F;&#x88AB;&#x5F31;&#x5F15;&#x7528;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;referrers&#x662F;&#x5B58;&#x50A8;&#x5F31;&#x5F15;&#x7528;&#x53D8;&#x91CF;&#x7684;&#x5730;&#x5740;&#x3002;&#x518D;&#x5224;&#x65AD;referent&#x662F;&#x5426;&#x4E3A;TaggedPointer&#x6216;&#x8005;nil&#xFF0C;&#x662F;&#x7684;&#x8BDD;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x3002;</p><p>&#x7136;&#x540E;&#x7528; weak_entry_for_referent &#x51FD;&#x6570;&#x641C;&#x7D22;&#x5BF9;&#x8C61;&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x6709;&#x4E86; weak_entry_t &#x7C7B;&#x578B;&#x7684;&#x6761;&#x76EE;&#xFF0C;&#x6709;&#x7684;&#x8BDD;&#x5219;&#x4F7F;&#x7528; append_referrer &#x628A;referrer&#x6DFB;&#x52A0;&#x5230;&#x91CC;&#x9762;&#xFF0C;&#x6CA1;&#x6709;&#x7684;&#x8BDD;&#x65B0;&#x5EFA;&#x4E00;&#x4E2A; weak_entry_t &#x6761;&#x76EE;&#xFF0C;&#x7136;&#x540E;&#x4F7F;&#x7528; weak_grow_maybe &#x51FD;&#x6570;&#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;&#x6269;&#x5927;&#x5F31;&#x5F15;&#x7528;&#x8868;&#x7684;&#x5927;&#x5C0F;&#xFF0C;&#x518D;&#x4F7F;&#x7528; weak_entry_insert &#x5C06;&#x5F31;&#x5F15;&#x7528;&#x63D2;&#x5165;&#x8868;&#x4E2D;&#x3002;</p><p>&#x5148;&#x770B;append_referrer&#x51FD;&#x6570;</p><!--kg-card-begin: markdown--><pre><code>static void append_referrer(weak_entry_t *entry, objc_object **new_referrer)
{
    if (! entry-&gt;out_of_line()) {
        // Try to insert inline.
        for (size_t i = 0; i &lt; WEAK_INLINE_COUNT; i++) {
            if (entry-&gt;inline_referrers[i] == nil) {
                entry-&gt;inline_referrers[i] = new_referrer;
                return;
            }
        }

        // Couldn&apos;t insert inline. Allocate out of line.
        weak_referrer_t *new_referrers = (weak_referrer_t *)
            calloc(WEAK_INLINE_COUNT, sizeof(weak_referrer_t));
        // This constructed table is invalid, but grow_refs_and_insert
        // will fix it and rehash it.
        for (size_t i = 0; i &lt; WEAK_INLINE_COUNT; i++) {
            new_referrers[i] = entry-&gt;inline_referrers[i];
        }
        entry-&gt;referrers = new_referrers;
        entry-&gt;num_refs = WEAK_INLINE_COUNT;
        entry-&gt;out_of_line_ness = REFERRERS_OUT_OF_LINE;
        entry-&gt;mask = WEAK_INLINE_COUNT-1;
        entry-&gt;max_hash_displacement = 0;
    }

    ASSERT(entry-&gt;out_of_line());

    if (entry-&gt;num_refs &gt;= TABLE_SIZE(entry) * 3/4) {
        return grow_refs_and_insert(entry, new_referrer);
    }
    size_t begin = w_hash_pointer(new_referrer) &amp; (entry-&gt;mask);
    size_t index = begin;
    size_t hash_displacement = 0;
    while (entry-&gt;referrers[index] != nil) {
        hash_displacement++;
        index = (index+1) &amp; entry-&gt;mask;
        if (index == begin) bad_weak_table(entry);
    }
    if (hash_displacement &gt; entry-&gt;max_hash_displacement) {
        entry-&gt;max_hash_displacement = hash_displacement;
    }
    weak_referrer_t &amp;ref = entry-&gt;referrers[index];
    ref = new_referrer;
    entry-&gt;num_refs++;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5927;&#x6982;&#x903B;&#x8F91;&#x5C31;&#x662F;&#xFF0C;&#x5148;&#x7528;weak_entry_t&#x4E2D;&#x7684;&#x6570;&#x7EC4;&#x5B58;&#x50A8;&#xFF0C;&#x5982;&#x679C;&#x6EE1;&#x4E86;&#x5C31;&#x6362;&#x54C8;&#x5E0C;&#x8868;&#x5B58;&#x50A8;&#x3002;</p><p>&#x518D;&#x770B;weak_grow_maybe&#x51FD;&#x6570;</p><!--kg-card-begin: markdown--><pre><code>#define TABLE_SIZE(entry) (entry-&gt;mask ? entry-&gt;mask + 1 : 0)

static void weak_grow_maybe(weak_table_t *weak_table)
{
    size_t old_size = TABLE_SIZE(weak_table);

    // Grow if at least 3/4 full.
    if (weak_table-&gt;num_entries &gt;= old_size * 3 / 4) {
        weak_resize(weak_table, old_size ? old_size*2 : 64);
    }
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5F53; weak_table &#x91CC;&#x7684;&#x5F31;&#x5F15;&#x7528;&#x6570;&#x91CF;&#x5230;&#x5B83;&#x5BB9;&#x91CF;&#x7684;&#x56DB;&#x5206;&#x4E4B;&#x4E09;&#x65F6;&#xFF0C;&#x4FBF;&#x4F1A;&#x5C06;&#x5BB9;&#x91CF;&#x62D3;&#x5C55;&#x4E3A;&#x4E24;&#x500D;&#x3002;&#x503C;&#x5F97;&#x6CE8;&#x610F;&#x7684;&#x662F;&#x7B2C;&#x4E00;&#x6B21;&#x62D3;&#x5C55;&#x4E5F;&#x5C31;&#x662F;&#x5F53; mask &#x4E3A; 0 &#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x521D;&#x59CB;&#x503C;&#x662F; 64&#x3002;</p><p>&#x6700;&#x540E;&#x662F;weak_entry_insert&#x51FD;&#x6570;</p><!--kg-card-begin: markdown--><pre><code>static void weak_entry_insert(weak_table_t *weak_table, weak_entry_t *new_entry)
{
    weak_entry_t *weak_entries = weak_table-&gt;weak_entries;
    ASSERT(weak_entries != nil);

    size_t begin = hash_pointer(new_entry-&gt;referent) &amp; (weak_table-&gt;mask);
    size_t index = begin;
    size_t hash_displacement = 0;
    while (weak_entries[index].referent != nil) {
        index = (index+1) &amp; weak_table-&gt;mask;
        if (index == begin) bad_weak_table(weak_entries);
        hash_displacement++;
    }

    weak_entries[index] = *new_entry;
    weak_table-&gt;num_entries++;

    if (hash_displacement &gt; weak_table-&gt;max_hash_displacement) {
        weak_table-&gt;max_hash_displacement = hash_displacement;
    }
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5148;&#x5224;&#x65AD;&#x54C8;&#x5E0C;&#x8868;&#x662F;&#x5426;&#x5B58;&#x5728;&#xFF0C;&#x4E0D;&#x5B58;&#x5728;&#x8BC1;&#x660E;&#x5F31;&#x5F15;&#x7528;&#x7684;&#x6570;&#x91CF;&#x4E0D;&#x5927;&#x4E8E;4&#x4E2A;&#xFF0C;&#x8FD8;&#x4F7F;&#x7528;&#x6570;&#x7EC4;&#x5B58;&#x50A8;&#x3002;&#x5B58;&#x5728;&#x7684;&#x8BDD;&#x5C31;&#x662F;&#x54C8;&#x5E0C;&#x8868;&#x63D2;&#x5165;&#x7684;&#x8FC7;&#x7A0B;&#x3002;</p><p>&#x4E0B;&#x9762;&#x770B;weak_unregister_no_lock</p><!--kg-card-begin: markdown--><pre><code>void
weak_unregister_no_lock(weak_table_t *weak_table, id referent_id, 
                        id *referrer_id)
{
    objc_object *referent = (objc_object *)referent_id;
    objc_object **referrer = (objc_object **)referrer_id;

    weak_entry_t *entry;

    if (!referent) return;

    if ((entry = weak_entry_for_referent(weak_table, referent))) {
        remove_referrer(entry, referrer);
        bool empty = true;
        if (entry-&gt;out_of_line()  &amp;&amp;  entry-&gt;num_refs != 0) {
            empty = false;
        }
        else {
            for (size_t i = 0; i &lt; WEAK_INLINE_COUNT; i++) {
                if (entry-&gt;inline_referrers[i]) {
                    empty = false; 
                    break;
                }
            }
        }

        if (empty) {
            weak_entry_remove(weak_table, entry);
        }
    }

    // Do not set *referrer = nil. objc_storeWeak() requires that the 
    // value not change.
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5148;&#x4F7F;&#x7528; weak_entry_for_referent &#x51FD;&#x6570;&#x627E;&#x5230;&#x5BF9;&#x5E94;&#x7684;&#x5F31;&#x5F15;&#x7528;&#x6761;&#x76EE;&#xFF0C;&#x5E76;&#x7528; remove_referrer &#x5C06;&#x5BF9;&#x5E94;&#x7684;&#x5F31;&#x5F15;&#x7528;&#x53D8;&#x91CF;&#x4F4D;&#x7F6E;&#x4ECE;&#x4E2D;&#x79FB;&#x9664;&#x3002;&#x6700;&#x540E;&#x5224;&#x65AD;&#x6761;&#x76EE;&#x662F;&#x5426;&#x4E3A;&#x7A7A;&#xFF0C;&#x4E3A;&#x7A7A;&#x5219;&#x4F7F;&#x7528; weak_entry_remove &#x5C06;&#x5176;&#x4ECE;&#x5F31;&#x5F15;&#x7528;&#x8868;&#x4E2D;&#x79FB;&#x9664;&#x3002;</p><p>remove_referrer&#x51FD;&#x6570;&#x5B9E;&#x73B0;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>static void remove_referrer(weak_entry_t *entry, objc_object **old_referrer)
{
    if (! entry-&gt;out_of_line()) {
        for (size_t i = 0; i &lt; WEAK_INLINE_COUNT; i++) {
            if (entry-&gt;inline_referrers[i] == old_referrer) {
                entry-&gt;inline_referrers[i] = nil;
                return;
            }
        }
        _objc_inform(&quot;Attempted to unregister unknown __weak variable &quot;
                     &quot;at %p. This is probably incorrect use of &quot;
                     &quot;objc_storeWeak() and objc_loadWeak(). &quot;
                     &quot;Break on objc_weak_error to debug.\n&quot;, 
                     old_referrer);
        objc_weak_error();
        return;
    }

    size_t begin = w_hash_pointer(old_referrer) &amp; (entry-&gt;mask);
    size_t index = begin;
    size_t hash_displacement = 0;
    while (entry-&gt;referrers[index] != old_referrer) {
        index = (index+1) &amp; entry-&gt;mask;
        if (index == begin) bad_weak_table(entry);
        hash_displacement++;
        if (hash_displacement &gt; entry-&gt;max_hash_displacement) {
            _objc_inform(&quot;Attempted to unregister unknown __weak variable &quot;
                         &quot;at %p. This is probably incorrect use of &quot;
                         &quot;objc_storeWeak() and objc_loadWeak(). &quot;
                         &quot;Break on objc_weak_error to debug.\n&quot;, 
                         old_referrer);
            objc_weak_error();
            return;
        }
    }
    entry-&gt;referrers[index] = nil;
    entry-&gt;num_refs--;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5148;&#x5224;&#x65AD;&#x662F;&#x5426;&#x662F;inline&#x5B58;&#x50A8;&#xFF08;! entry-&gt;out_of_line()&#xFF09;&#xFF0C;&#x5982;&#x679C;&#x662F;&#x7684;&#x8BDD;&#x628A;old_referrer&#x76F4;&#x63A5;&#x8BBE;&#x7F6E;&#x4E3A;nil (entry-&gt;inline_referrers[i] = nil)&#xFF0C;&#x4E0D;&#x662F;&#x7684;&#x8BDD;&#x904D;&#x5386;&#x54C8;&#x5E0C;&#x8868;referrers&#x627E;&#x5230;&#x7D22;&#x5F15;&#xFF0C;&#x518D;&#x901A;&#x8FC7;&#x7D22;&#x5F15;&#x8BBE;&#x7F6E;&#x4E3A;nil&#xFF08;entry-&gt;referrers[index] = nil&#xFF09;&#xFF0C;&#x7136;&#x540E;&#x5C06;&#x957F;&#x5EA6;-1&#x3002;</p><p>&#x7136;&#x540E;&#x770B;weak_entry_remove&#x65B9;&#x6CD5;</p><!--kg-card-begin: markdown--><pre><code>static void weak_entry_remove(weak_table_t *weak_table, weak_entry_t *entry)
{
    // remove entry
    if (entry-&gt;out_of_line()) free(entry-&gt;referrers);
    bzero(entry, sizeof(*entry));

    weak_table-&gt;num_entries--;

    weak_compact_maybe(weak_table);
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x76F4;&#x63A5;&#x7684;&#x6E05;&#x96F6; entry&#xFF0C;&#x5E76;&#x7ED9; weak_table &#x7684; num_entries &#x51CF; 1&#xFF0C;&#x6700;&#x540E;&#x8C03;&#x7528;weak_compact_maybe&#x65B9;&#x6CD5;&#x68C0;&#x67E5;&#x770B;weak_table&#x662F;&#x5426;&#x9700;&#x8981;&#x7F29;&#x5C0F;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>static void weak_compact_maybe(weak_table_t *weak_table)
{
    size_t old_size = TABLE_SIZE(weak_table);

    // Shrink if larger than 1024 buckets and at most 1/16 full.
    if (old_size &gt;= 1024  &amp;&amp; old_size / 16 &gt;= weak_table-&gt;num_entries) {
        weak_resize(weak_table, old_size / 8);
        // leaves new table no more than 1/2 full
    }
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x7F29;&#x5C0F;&#x7684;&#x8BDD;&#x5219;&#x662F;&#x9700;&#x8981;&#x8868;&#x672C;&#x8EAB;&#x5927;&#x4E8E;&#x7B49;&#x4E8E; 1024 &#x5E76;&#x4E14;&#x5B58;&#x653E;&#x4E86;&#x4E0D;&#x8DB3;&#x5341;&#x516D;&#x5206;&#x4E4B;&#x4E00;&#x7684;&#x6761;&#x76EE;&#x65F6;&#xFF0C;&#x76F4;&#x63A5;&#x901A;&#x8FC7;weak_resize&#x65B9;&#x6CD5;&#x7F29;&#x5C0F; 8 &#x500D;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>static void weak_resize(weak_table_t *weak_table, size_t new_size)
{
    size_t old_size = TABLE_SIZE(weak_table);

    weak_entry_t *old_entries = weak_table-&gt;weak_entries;
    weak_entry_t *new_entries = (weak_entry_t *)
        calloc(new_size, sizeof(weak_entry_t));

    weak_table-&gt;mask = new_size - 1;
    weak_table-&gt;weak_entries = new_entries;
    weak_table-&gt;max_hash_displacement = 0;
    weak_table-&gt;num_entries = 0;  // restored by weak_entry_insert below
    
    if (old_entries) {
        weak_entry_t *entry;
        weak_entry_t *end = old_entries + old_size;
        for (entry = old_entries; entry &lt; end; entry++) {
            if (entry-&gt;referent) {
                weak_entry_insert(weak_table, entry);
            }
        }
        free(old_entries);
    }
}
</code></pre>
<!--kg-card-end: markdown--><p>weak_resize &#x51FD;&#x6570;&#x7684;&#x8FC7;&#x7A0B;&#x5C31;&#x662F;&#x65B0;&#x5EFA;&#x4E00;&#x4E2A;&#x6570;&#x7EC4;&#xFF0C;&#x5C06;&#x8001;&#x6570;&#x7EC4;&#x91CC;&#x7684;&#x503C;&#x4F7F;&#x7528; weak_entry_insert &#x51FD;&#x6570;&#x6DFB;&#x52A0;&#x8FDB;&#x53BB;&#xFF0C;mask&#x662F;&#x65B0;&#x6570;&#x7EC4;&#x957F;&#x5EA6;-1&#xFF0C;max_hash_displacement &#x548C; num_entries &#x4E5F;&#x90FD;&#x6E05;&#x96F6;&#x4E86;&#xFF0C;&#x56E0;&#x4E3A; weak_entry_insert &#x51FD;&#x6570;&#x4F1A;&#x5BF9;&#x8FD9;&#x4E24;&#x4E2A;&#x503C;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#x3002;</p><p>&#x5230;&#x8FD9;&#x91CC;&#xFF0C;&#x5F31;&#x5F15;&#x7528;&#x7684;&#x6574;&#x4E2A;&#x6D41;&#x7A0B;&#x5DF2;&#x7ECF;&#x5206;&#x6790;&#x5B8C;&#x6210;&#x4E86;&#x3002;&#x73B0;&#x5728;&#x770B;&#x4E0B;&#x4E3A;&#x4EC0;&#x4E48;&#x5BF9;&#x8C61;&#x9500;&#x6BC1;&#x540E;&#xFF0C;&#x5F31;&#x5F15;&#x7528;&#x53D8;&#x91CF;&#x88AB;&#x7F6E;&#x4E3A; nil&#x3002;&#x901A;&#x8FC7;&#x641C;&#x7D22;&#x627E;&#x5230;&#x5BF9;&#x8C61;&#x5728;&#x662F;&#x5426;&#x7684;&#x65F6;&#x5019;&#x8C03;&#x7528;&#x4E86;&#x4EE5;&#x4E0B;&#x65B9;&#x6CD5;</p><!--kg-card-begin: markdown--><pre><code>void
objc_object::clearDeallocating_slow()
{
    ASSERT(isa().nonpointer  &amp;&amp;  (isa().weakly_referenced || isa().has_sidetable_rc));

    SideTable&amp; table = SideTables()[this];
    table.lock();
    if (isa().weakly_referenced) {
        weak_clear_no_lock(&amp;table.weak_table, (id)this);
    }
    if (isa().has_sidetable_rc) {
        table.refcnts.erase(this);
    }
    table.unlock();
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5982;&#x679C;&#x5BF9;&#x8C61;&#x6709;&#x5F31;&#x5F15;&#x7528;&#x4F1A;&#x8C03;&#x7528;weak_clear_no_lock&#x65B9;&#x6CD5;</p><!--kg-card-begin: markdown--><pre><code>void 
weak_clear_no_lock(weak_table_t *weak_table, id referent_id) 
{
    objc_object *referent = (objc_object *)referent_id;

    weak_entry_t *entry = weak_entry_for_referent(weak_table, referent);
    if (entry == nil) {
        /// XXX shouldn&apos;t happen, but does with mismatched CF/objc
        //printf(&quot;XXX no entry for clear deallocating %p\n&quot;, referent);
        return;
    }

    // zero out references
    weak_referrer_t *referrers;
    size_t count;
    
    if (entry-&gt;out_of_line()) {
        referrers = entry-&gt;referrers;
        count = TABLE_SIZE(entry);
    } 
    else {
        referrers = entry-&gt;inline_referrers;
        count = WEAK_INLINE_COUNT;
    }
    
    for (size_t i = 0; i &lt; count; ++i) {
        objc_object **referrer = referrers[i];
        if (referrer) {
            if (*referrer == referent) {
                *referrer = nil;
            }
            else if (*referrer) {
                _objc_inform(&quot;__weak variable at %p holds %p instead of %p. &quot;
                             &quot;This is probably incorrect use of &quot;
                             &quot;objc_storeWeak() and objc_loadWeak(). &quot;
                             &quot;Break on objc_weak_error to debug.\n&quot;, 
                             referrer, (void*)*referrer, (void*)referent);
                objc_weak_error();
            }
        }
    }
    
    weak_entry_remove(weak_table, entry);
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x5148;&#x83B7;&#x53D6;&#x5B58;&#x50A8;&#x5F31;&#x5F15;&#x7528;&#x7684;weak_entry_t&#xFF0C;&#x7136;&#x540E;&#x4ECE;&#x4E2D;&#x83B7;&#x53D6;&#x5230;&#x5B58;&#x50A8;&#x7684;&#x4F4D;&#x7F6E;&#x548C;&#x6570;&#x91CF;&#xFF0C;&#x518D;&#x904D;&#x5386;&#x8BBE;&#x7F6E;&#x4E3A;nil&#xFF0C;&#x6700;&#x540E;&#x4ECE;weak_table&#x4E2D;&#x5220;&#x9664;&#x3002;</p><p>&#x901A;&#x8FC7;&#x5206;&#x6790;&#x6D41;&#x7A0B;&#x53EF;&#x4EE5;&#x5F97;&#x77E5;&#x5F31;&#x5F15;&#x7528;&#x7684;&#x5B58;&#x50A8;&#x7ED3;&#x6784; SideTables-&gt;SideTable-&gt;weak_table_t-&gt;weak_entry_t-&gt;weak_referrer_t&#x6570;&#x7EC4;&#x6216;&#x8005;&#x54C8;&#x5E0C;&#x8868;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[编译调试objc4-841.13源码]]></title><description><![CDATA[<p>&#x4ECE;&#x82F9;&#x679C;&#x5F00;&#x6E90;&#x7F51;&#x7AD9;<a href="https://opensource.apple.com/releases/?ref=lemonlie.com">https://opensource.apple.com/releases/</a>&#x4E0B;&#x8F7D;&#x6700;&#x65B0;&#x6E90;&#x7801;&#xFF0C;&#x8FD9;&#x91CC;&#x662F;<a href="https://github.com/apple-oss-distributions/objc4/archive/objc4-841.13.tar.gz?ref=lemonlie.com">objc4-841.13</a>&#x7248;&#x672C;&#xFF0C;&#x5404;&#x4E2A;&#x7248;&#x672C;&#x9700;&#x8981;&#x5904;&#x7406;&#x7684;&#x95EE;&#x9898;&#x5DEE;&#x522B;&#x4E0D;&#x662F;&#x5F88;&#x5927;&#x3002;&#x7F16;&#x8BD1;&#x73AF;&#x5883;&#x5982;</p>]]></description><link>https://lemonlie.com/compile-and-debug-objc4-841-13-source-code/</link><guid isPermaLink="false">65672ee96c00b44e30765790</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Sun, 26 Jun 2022 09:34:06 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1603468620905-8de7d86b781e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE4fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1603468620905-8de7d86b781e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE4fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;"><p>&#x4ECE;&#x82F9;&#x679C;&#x5F00;&#x6E90;&#x7F51;&#x7AD9;<a href="https://opensource.apple.com/releases/?ref=lemonlie.com">https://opensource.apple.com/releases/</a>&#x4E0B;&#x8F7D;&#x6700;&#x65B0;&#x6E90;&#x7801;&#xFF0C;&#x8FD9;&#x91CC;&#x662F;<a href="https://github.com/apple-oss-distributions/objc4/archive/objc4-841.13.tar.gz?ref=lemonlie.com">objc4-841.13</a>&#x7248;&#x672C;&#xFF0C;&#x5404;&#x4E2A;&#x7248;&#x672C;&#x9700;&#x8981;&#x5904;&#x7406;&#x7684;&#x95EE;&#x9898;&#x5DEE;&#x522B;&#x4E0D;&#x662F;&#x5F88;&#x5927;&#x3002;&#x7F16;&#x8BD1;&#x73AF;&#x5883;&#x5982;&#x4E0B;</p><ul>
<li>&#x7CFB;&#x7EDF;: macOS 12.4 (21F79)</li>
<li>&#x5DE5;&#x5177;: Xcode 13.4.1 (13F100)</li>
<li>&#x6E90;&#x7801;: objc4-841.13</li>
</ul>
<hr><p>&#x4E0B;&#x8F7D;&#x597D;&#x4EE3;&#x7801;&#x89E3;&#x538B;&#xFF0C;&#x6253;&#x5F00;&#x540E;&#x7F16;&#x8BD1;objc Target&#x3002;&#x4E0B;&#x9762;&#x6309;&#x7167;&#x9519;&#x8BEF;&#x51FA;&#x73B0;&#x7684;&#x987A;&#x5E8F;&#xFF0C;&#x4F9D;&#x6B21;&#x89E3;&#x51B3;&#x3002;</p><p>1&#x3001;unable to find sdk &apos;macosx.internal&apos;</p><p>&#x5206;&#x522B;&#x9009;objc&#x548C;objc-trampolines&#x4E24;&#x4E2A;target&#xFF0C;&#x7136;&#x540E;&#x628A;Base SDK&#x9009;&#x4E3A;macOS&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/1655993096540.jpg" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="647" srcset="https://lemonlie.com/content/images/size/w600/2022/06/1655993096540.jpg 600w, https://lemonlie.com/content/images/size/w1000/2022/06/1655993096540.jpg 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/1655993096540.jpg 1600w, https://lemonlie.com/content/images/2022/06/1655993096540.jpg 2264w" sizes="(min-width: 720px) 720px"></figure><p>2&#x3001;&apos;sys/reason.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/1656077786191.jpg" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="492" srcset="https://lemonlie.com/content/images/size/w600/2022/06/1656077786191.jpg 600w, https://lemonlie.com/content/images/size/w1000/2022/06/1656077786191.jpg 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/1656077786191.jpg 1600w, https://lemonlie.com/content/images/2022/06/1656077786191.jpg 2258w" sizes="(min-width: 720px) 720px"></figure><p>&#x5934;&#x6587;&#x4EF6;&#x7F3A;&#x5931;&#xFF0C;&#x53EA;&#x8981;&#x627E;&#x5230;&#x5BF9;&#x5E94;&#x7684;&#x5934;&#x6587;&#x4EF6;&#x6DFB;&#x52A0;&#x5230;&#x5DE5;&#x7A0B;&#x4E2D;&#x5C31;&#x53EF;&#x4EE5;&#x89E3;&#x51B3;&#xFF0C;&#x9996;&#x5148;&#x5728;&#x5DE5;&#x7A0B;&#x7684;&#x6839;&#x76EE;&#x5F55;&#x521B;&#x5EFA;include&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x7136;&#x540E;&#x5728;&#x5DE5;&#x7A0B;&#x7684;Build Settings-&gt;Header Search Paths&#x6DFB;&#x52A0;$(SRCROOT)/include&#xFF0C;&#x5E76;&#x4E14;&#x628A;&#x540E;&#x9762;&#x9009;&#x9879;&#x8BBE;&#x7F6E;&#x4E3A;recursive&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/1656078650899.jpg" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1892" height="712" srcset="https://lemonlie.com/content/images/size/w600/2022/06/1656078650899.jpg 600w, https://lemonlie.com/content/images/size/w1000/2022/06/1656078650899.jpg 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/1656078650899.jpg 1600w, https://lemonlie.com/content/images/2022/06/1656078650899.jpg 1892w" sizes="(min-width: 720px) 720px"></figure><p>&#x56E0;&#x4E3A;&#x5934;&#x6587;&#x4EF6;&#x662F;&lt;sys/reason.h&gt;&#xFF0C;&#x6240;&#x4EE5;&#x8FD8;&#x8981;&#x5728;include&#x6587;&#x4EF6;&#x5939;&#x4E2D;&#x521B;&#x5EFA;sys&#x6587;&#x4EF6;&#x5939;&#x3002;&#x7136;&#x540E;&#x5728;<a href="https://github.com/apple-oss-distributions/xnu/archive/xnu-8020.121.3.tar.gz?ref=lemonlie.com">xnu-8020.121.3</a>&#x7684;/bsd/sys&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;reason.h&#xFF0C;&#x590D;&#x5236;&#x5230;&#x65B0;&#x5EFA;&#x7684;/include/sys&#x76EE;&#x5F55;&#x3002;</p><p>3&#x3001;&apos;mach-o/dyld_priv.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/1656080625285.jpg" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="469" srcset="https://lemonlie.com/content/images/size/w600/2022/06/1656080625285.jpg 600w, https://lemonlie.com/content/images/size/w1000/2022/06/1656080625285.jpg 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/1656080625285.jpg 1600w, https://lemonlie.com/content/images/2022/06/1656080625285.jpg 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x9700;&#x8981;&#x5148;&#x5728;include&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x9762;&#x521B;&#x5EFA;mach-o&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x7136;&#x540E;&#x5728;dyld-957&#x7684;/include/mach-o&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;dyld_priv.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/mach-o&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>4&#x3001;&apos;os/lock_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-2.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="487" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-2.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-2.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-2.png 1600w, https://lemonlie.com/content/images/2022/06/image-2.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x9700;&#x8981;&#x5148;&#x5728;include&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x9762;&#x521B;&#x5EFA;os&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x7136;&#x540E;&#x5728;<a href="https://github.com/apple-oss-distributions/libplatform/archive/libplatform-273.100.5.tar.gz?ref=lemonlie.com">libplatform-273.100.5</a>&#x7684;/private/os&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;lock_private.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/os&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>5&#x3001;Expected &apos;,&apos;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-3.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="465" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-3.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-3.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-3.png 1600w, https://lemonlie.com/content/images/2022/06/image-3.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x5220;&#x9664;&#x6587;&#x4EF6;&#x4E2D;&#x6240;&#x6709;&#x7684;bridgeos(3.0)&#xFF0C;&#x5E26;&#x524D;&#x9762;&apos;&#xFF0C;&apos;&#x4E00;&#x5E76;&#x5220;&#x9664;&#xFF0C;&#x641C;&#x7D22;&#x66FF;&#x6362;&#x5373;&#x53EF;&#xFF0C;&#x5982;&#x4E0B;&#x56FE;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-4.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="373" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-4.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-4.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-4.png 1600w, https://lemonlie.com/content/images/2022/06/image-4.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x540E;&#x9762;&#x8FD8;&#x4F1A;&#x51FA;&#x73B0;bridgeos&#x76F8;&#x5173;&#x7684;&#x62A5;&#x9519;&#xFF0C;&#x4E00;&#x5E76;&#x5220;&#x9664;&#x5373;&#x53EF;&#x3002;</p><p>6&#x3001;&apos;os/base_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-5.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="341" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-5.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-5.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-5.png 1600w, https://lemonlie.com/content/images/2022/06/image-5.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x5728;<a href="https://github.com/apple-oss-distributions/libplatform/archive/libplatform-220.100.1.tar.gz?ref=lemonlie.com">libplatform-220.100.1</a>&#x7684;/private/os&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;base_private.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/os&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>7&#x3001;&apos;pthread/tsd_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-6.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="386" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-6.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-6.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-6.png 1600w, https://lemonlie.com/content/images/2022/06/image-6.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x9700;&#x8981;&#x5148;&#x5728;include&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x9762;&#x521B;&#x5EFA;pthread&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x7136;&#x540E;&#x5728;<a href="https://github.com/apple-oss-distributions/libpthread/archive/libpthread-486.100.11.tar.gz?ref=lemonlie.com">libpthread-486.100.11</a>&#x7684;/private/pthread&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;tsd_private.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/pthread&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>8&#x3001;&apos;System/machine/cpu_capabilities.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-7.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="469" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-7.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-7.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-7.png 1600w, https://lemonlie.com/content/images/2022/06/image-7.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x9700;&#x8981;&#x5728;include&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x521B;&#x5EFA;System&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x7136;&#x540E;&#x518D;System&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x521B;&#x5EFA;machine&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x7136;&#x540E;&#x5728;xnu-8020.121.3&#x7684;/osfmk/machine&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;cpu_capabilities.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/System/machin&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>9&#x3001;&apos;os/tsd.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-8.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="480" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-8.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-8.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-8.png 1600w, https://lemonlie.com/content/images/2022/06/image-8.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x5728;xnu-8020.121.3&#x7684;/libsyscall/os&#x4E0B;&#x627E;&#x5230;tsd.h&#x6587;&#x4EF6;&#xFF0C;&#x590D;&#x5236;&#x5230;/include/os&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>10&#x3001;&apos;pthread/spinlock_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-9.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="481" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-9.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-9.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-9.png 1600w, https://lemonlie.com/content/images/2022/06/image-9.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x5728;libpthread-486.100.11&#x7684;/private/pthread&#x4E0B;&#x627E;&#x5230;spinlock_private.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/pthread&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>11&#x3001;&apos;os/feature_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-10.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="477" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-10.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-10.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-10.png 1600w, https://lemonlie.com/content/images/2022/06/image-10.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;<a href="https://github.com/CodeTips/apple_internal_sdk?ref=lemonlie.com">apple_internal_sdk</a>&#x7684;/usr/include/os&#x76EE;&#x5F55;&#x4E2D;&#x627E;&#x5230;feature_private.h&#x6587;&#x4EF6;&#xFF0C;&#x590D;&#x5236;&#x5230;/include/os&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>12&#x3001;&apos;os/variant_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-11.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="402" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-11.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-11.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-11.png 1600w, https://lemonlie.com/content/images/2022/06/image-11.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;<a href="https://github.com/apple-oss-distributions/Libc/archive/Libc-1507.100.9.tar.gz?ref=lemonlie.com">Libc-1507.100.9</a> &#x7684;/os&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;variant_private.h&#x6587;&#x4EF6;&#xFF0C;&#x590D;&#x5236;&#x5230;/include/os&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>13&#x3001;&apos;System/pthread_machdep.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-12.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="430" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-12.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-12.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-12.png 1600w, https://lemonlie.com/content/images/2022/06/image-12.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;<a href="https://github.com/apple-oss-distributions/Libc/archive/Libc-825.26.tar.gz?ref=lemonlie.com">Libc-825.26</a>&#x7684;/pthreads&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;pthread_machdep.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/System&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>14&#x3001;&apos;CrashReporterClient.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-13.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="359" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-13.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-13.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-13.png 1600w, https://lemonlie.com/content/images/2022/06/image-13.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>1.&#x4ECE;Libc-825.26&#x7684;/include&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;CrashReporterClient.h&#x6587;&#x4EF6;&#xFF0C;&#x590D;&#x5236;&#x5230;objc&#x5DE5;&#x7A0B;&#x4E2D;&#x81EA;&#x5DF1;&#x521B;&#x5EFA;&#x7684;include&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>2.&#x590D;&#x5236;&#x5B8C;&#x6210;&#x8FD8;&#x662F;&#x4F1A;&#x62A5;&#x9519;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-14.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="578" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-14.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-14.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-14.png 1600w, https://lemonlie.com/content/images/2022/06/image-14.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x9700;&#x8981;&#x5728;&#x62A5;&#x9519;&#x6587;&#x4EF6;&#x4E2D;&#x6DFB;&#x52A0;#define LIBC_NO_LIBCRASHREPORTERCLIENT</p><p>3.&#x5728;Build Settings-&gt;Linking-&gt;Other Linker Flags&#x91CC;&#x5220;&#x6389;&quot;-lCrashReporterClient&quot;&#xFF0C;&#x56E0;&#x4E3A;&#x540E;&#x9762;&#x8FD0;&#x884C;&#x7684;&#x65F6;&#x5019;&#x4F1A;&#x62A5;&#x9519;ld: library not found for -lCrashReporterClient</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-15.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="827" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-15.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-15.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-15.png 1600w, https://lemonlie.com/content/images/2022/06/image-15.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>15&#x3001;Typedef redefinition with different types (&apos;int&apos; vs &apos;volatile OSSpinLock&apos; (aka &apos;volatile int&apos;)) &#x7B49;&#xFF0C;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-17.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="382" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-17.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-17.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-17.png 1600w, https://lemonlie.com/content/images/2022/06/image-17.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x4E0A;&#x9762;pthread_machdep.h&#x4E2D;&#x7684;&#x56DB;&#x4E2A;&#x62A5;&#x9519;&#xFF0C;&#x6CE8;&#x91CA;&#x6389;&#x5373;&#x53EF;&#x3002;</p><p>16&#x3001;&apos;os/bsd.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-18.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="327" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-18.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-18.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-18.png 1600w, https://lemonlie.com/content/images/2022/06/image-18.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x6CE8;&#x91CA;&#x6389;&#x5373;&#x53EF;&#xFF0C;&#x7136;&#x540E;&#x6CE8;&#x91CA;is_root_ramdisk&#x65B9;&#x6CD5;&#x548C;&#x8C03;&#x7528;&#x6B64;&#x65B9;&#x6CD5;&#x7684;&#x5730;&#x65B9;&#x3002;</p><p>17&#x3001;&apos;os/reason_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-26.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="433" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-26.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-26.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-26.png 1600w, https://lemonlie.com/content/images/2022/06/image-26.png 2264w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;xnu-8020.121.3&#x7684;/libkern/os&#x7684;&#x76EE;&#x5F55;&#x4E0B;&#x627E;&#x5230;reason_private.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/os&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>18&#x3001;&apos;objc-shared-cache.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-27.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="287" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-27.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-27.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-27.png 1600w, https://lemonlie.com/content/images/2022/06/image-27.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;dyld-957&#x7684;/include&#x76EE;&#x5F55;&#x4E2D;&#x627E;&#x5230;objc-shared-cache.h&#xFF0C;&#x590D;&#x5236;&#x5230;objc&#x5DE5;&#x7A0B;&#x7684;include&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p><p>19&#x3001;Use of undeclared identifier &apos;dyld_platform_version_*</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-29.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1694" height="114" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-29.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-29.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-29.png 1600w, https://lemonlie.com/content/images/2022/06/image-29.png 1694w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-28.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1630" height="150" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-28.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-28.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-28.png 1600w, https://lemonlie.com/content/images/2022/06/image-28.png 1630w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-38.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1680" height="98" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-38.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-38.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-38.png 1600w, https://lemonlie.com/content/images/2022/06/image-38.png 1680w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-37.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy"></figure><p>&#x6CE8;&#x91CA;&#x6216;&#x8005;&#x5220;&#x9664;&#x5373;&#x53EF;&#x3002;</p><p>20&#x3001;&apos;_simple.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-30.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="373" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-30.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-30.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-30.png 1600w, https://lemonlie.com/content/images/2022/06/image-30.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;libplatform-220.100.1&#x7684;/private&#x76EE;&#x5F55;&#x627E;&#x5230;_simple.h&#xFF0C;&#x590D;&#x5236;&#x5230;objc&#x5DE5;&#x7A0B;&#x7684;include&#x76EE;&#x5F55;&#x3002;</p><p>21&#x3001;&apos;os/linker_set.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-33.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="347" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-33.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-33.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-33.png 1600w, https://lemonlie.com/content/images/2022/06/image-33.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;xnu-8020.121.3&#x7684;/bsd/sys&#x76EE;&#x5F55;&#x627E;&#x5230;linker_set.h&#xFF0C;&#x590D;&#x5236;&#x5230;/include/os&#x76EE;&#x5F55;&#x3002;</p><p>22&#x3001;&apos;Block_private.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-34.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="340" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-34.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-34.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-34.png 1600w, https://lemonlie.com/content/images/2022/06/image-34.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x4ECE;<a href="https://github.com/apple-oss-distributions/libclosure/archive/libclosure-79.1.tar.gz?ref=lemonlie.com">libclosure-79.1</a>&#x6839;&#x76EE;&#x5F55;&#x627E;&#x5230;Block_private.h&#xFF0C;&#x590D;&#x5236;&#x5230;objc&#x5DE5;&#x7A0B;&#x7684;include&#x76EE;&#x5F55;&#x3002;</p><p>23&#x3001;&apos;Cambria/Traps.h&apos; file not found&#x548C;&apos;Cambria/Cambria.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-35.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="412" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-35.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-35.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-35.png 1600w, https://lemonlie.com/content/images/2022/06/image-35.png 2262w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-40.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1692" height="406" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-40.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-40.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-40.png 1600w, https://lemonlie.com/content/images/2022/06/image-40.png 1692w" sizes="(min-width: 720px) 720px"></figure><p>&#x6CE8;&#x91CA;&#x6389;&#x3002;&#x7B2C;&#x4E8C;&#x4E2A;&#x56FE;&#x7247;&#x9664;&#x4E86;&#x7EA2;&#x8272;&#x6846;&#x4F4F;&#x7684;&#xFF0C;&#x90FD;&#x6CE8;&#x91CA;&#x6389;&#x3002;&#x5C31;&#x7B97;&#x5934;&#x6587;&#x4EF6;&#x6B63;&#x5E38;&#x5BFC;&#x5165;&#xFF0C;&#x4E5F;&#x4F1A;&#x63D0;&#x793A;&#x4EE5;&#x4E0B;&#x9519;&#x8BEF;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-41.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="680" height="70" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-41.png 600w, https://lemonlie.com/content/images/2022/06/image-41.png 680w"></figure><p>24&#x3001;&apos;kern/restartable.h&apos; file not found</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-36.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="288" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-36.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-36.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-36.png 1600w, https://lemonlie.com/content/images/2022/06/image-36.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x5728;xnu-8020.121.3&#x7684;/osfmk/kern&#x627E;&#x5230;restartable.h&#xFF0C;&#x7136;&#x540E;&#x5728;objc&#x5DE5;&#x7A0B;&#x7684;include&#x76EE;&#x5F55;&#x4E0B;&#x521B;&#x5EFA;kern&#x6587;&#x4EF6;&#x5939;&#xFF0C;&#x518D;&#x628A;&#x627E;&#x5230;&#x7684;&#x6587;&#x4EF6;&#x590D;&#x5236;&#x8FDB;&#x53BB;&#x3002;</p><p>25&#x3001;ld: library not found for -loah</p><p>&#x5728;Build Settings -&gt; Linking -&gt; Other Linker Flags&#x91CC;&#x5220;&#x6389;-loah</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-39.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="870" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-39.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-39.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-39.png 1600w, https://lemonlie.com/content/images/2022/06/image-39.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>26&#x3001;&apos;_static_assert&apos; declared as an array with a negative size</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-42.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1676" height="100" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-42.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-42.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-42.png 1600w, https://lemonlie.com/content/images/2022/06/image-42.png 1676w" sizes="(min-width: 720px) 720px"></figure><p>&#x6CE8;&#x91CA;&#x6389;&#x3002;</p><p>27&#x3001;SDK &quot;macosx.internal&quot; cannot be located.</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-43.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1688" height="408" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-43.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-43.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-43.png 1600w, https://lemonlie.com/content/images/2022/06/image-43.png 1688w" sizes="(min-width: 720px) 720px"></figure><p>&#x9009;&#x62E9; target -&gt; objc -&gt; Build Phases -&gt; Run Script(markgc)&#xFF0C;&#x628A;&#x811A;&#x672C;&#x6587;&#x672C; macosx.internal &#x6539;&#x6210; macosx&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-44.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="647" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-44.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-44.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-44.png 1600w, https://lemonlie.com/content/images/2022/06/image-44.png 2256w" sizes="(min-width: 720px) 720px"></figure><p>&#x5230;&#x8FD9;&#x4E00;&#x6B65;&#xFF0C;&#x5E94;&#x8BE5;&#x5C31;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x5730;&#x7F16;&#x8BD1;&#x4E86;&#x3002;</p><hr><p>&#x8C03;&#x8BD5;&#x90E8;&#x5206;&#xFF0C;&#x9700;&#x65B0;&#x5EFA;&#x4E2A;target-&gt;macOS-&gt;Command Line Tool</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-45.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="1460" height="1040" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-45.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-45.png 1000w, https://lemonlie.com/content/images/2022/06/image-45.png 1460w" sizes="(min-width: 720px) 720px"></figure><p>&#x7136;&#x540E;&#x5728;&#x65B0;&#x5EFA;&#x7684;target-&gt; Frameworks and Libraries -&gt; &#x6DFB;&#x52A0;&#x7F16;&#x8BD1;&#x51FA;&#x6765;&#x7684;libobjc.A.dylib</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-46.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="1292" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-46.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-46.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-46.png 1600w, https://lemonlie.com/content/images/2022/06/image-46.png 2264w" sizes="(min-width: 720px) 720px"></figure><p>&#x7136;&#x540E;&#x5728;&#x65B0;&#x5EFA;&#x7684;target-&gt;Build Settings-&gt;Enable hardened runtime&#x8BBE;&#x7F6E;&#x4E3A;NO</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-47.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="1292" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-47.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-47.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-47.png 1600w, https://lemonlie.com/content/images/2022/06/image-47.png 2264w" sizes="(min-width: 720px) 720px"></figure><p>&#x5728;&#x65B0;&#x5EFA;&#x7684;target&#x91CC;&#x9762;&#x968F;&#x4FBF;&#x65B0;&#x5EFA;&#x4E2A;&#x7C7B;&#x6587;&#x4EF6;&#xFF0C;&#x5E76;&#x4E14;&#x5728;main&#x6587;&#x4EF6;&#x4E2D;&#x521D;&#x59CB;&#x5316;&#x4E2A;&#x5BF9;&#x8C61;&#x3002;&#x7136;&#x540E;&#x5728;objc&#x7684;alloc&#x65B9;&#x6CD5;&#x6253;&#x65AD;&#x70B9;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-48.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="301" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-48.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-48.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-48.png 1600w, https://lemonlie.com/content/images/2022/06/image-48.png 2260w" sizes="(min-width: 720px) 720px"></figure><p>&#x5E76;&#x4E14;&#x5728;main&#x6587;&#x4EF6;&#x6253;&#x65AD;&#x70B9;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-50.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="649" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-50.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-50.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-50.png 1600w, https://lemonlie.com/content/images/2022/06/image-50.png 2262w" sizes="(min-width: 720px) 720px"></figure><p>&#x8FD0;&#x884C;&#xFF0C;&#x5982;&#x679C;alloc&#x6CA1;&#x6709;&#x65AD;&#x4F4F;&#xFF0C;&#x9700;&#x8981;&#x68C0;&#x67E5;Enable hardened runtime&#x662F;&#x5426;&#x8BBE;&#x7F6E;&#x4E3A;NO&#xFF0C;&#x5982;&#x679C;&#x7B2C;&#x4E8C;&#x4E2A;&#x6CA1;&#x65AD;&#x4F4F;&#xFF0C;&#x9700;&#x8981;&#x5728;Compile Sources&#x4E2D;&#x628A;main&#x6587;&#x4EF6;&#x79FB;&#x52A8;&#x5230;&#x5BF9;&#x4E0A;&#x9762;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image-51.png" class="kg-image" alt="&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;objc4-841.13&#x6E90;&#x7801;" loading="lazy" width="2000" height="839" srcset="https://lemonlie.com/content/images/size/w600/2022/06/image-51.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/image-51.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/image-51.png 1600w, https://lemonlie.com/content/images/2022/06/image-51.png 2264w" sizes="(min-width: 720px) 720px"></figure><hr><p>&#x6309;&#x7167;&#x4EE5;&#x4E0A;&#x6B65;&#x9AA4;&#x5904;&#x7406;&#x5B8C;&#x6210;&#xFF0C;&#x5C31;&#x4F1A;&#x5F97;&#x5230;&#x4E00;&#x4EFD;&#x53EF;&#x4EE5;&#x7F16;&#x8BD1;&#x8C03;&#x8BD5;&#x7684;<a href="https://github.com/CodeTips/objc4?ref=lemonlie.com">objc</a>&#x4EE3;&#x7801;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[Objective-C类结构分析(class_rw_t)]]></title><description><![CDATA[<p>&#x4E0A;&#x4E00;&#x7BC7;&#x5206;&#x6790;&#x4E86;cache_t&#x7684;&#x7ED3;&#x6784;&#x548C;&#x600E;&#x4E48;&#x7F13;&#x5B58;&#x65B9;&#x6CD5;&#x7684;&#xFF0C;&#x8FD9;&#x91CC;&#x7EE7;&#x7EED;&#x5206;&#x6790;objc_class&#x4E2D;&#x7684;class_data_bits_t&#xFF0C;&#x641C;&#x7D22;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x4E3B;&#x8981;&#x7ED3;&#x6784;&#x5982;&#x4E0B;</p><pre><code>struct class_data_</code></pre>]]></description><link>https://lemonlie.com/objective-clei-jie-gou-fen-xi/</link><guid isPermaLink="false">65672ee96c00b44e3076578f</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Sun, 19 Jun 2022 10:20:51 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1488229297570-58520851e868?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE5fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1488229297570-58520851e868?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE5fHxjb2RlfGVufDB8fHx8MTcwMTI2OTE0M3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Objective-C&#x7C7B;&#x7ED3;&#x6784;&#x5206;&#x6790;(class_rw_t)"><p>&#x4E0A;&#x4E00;&#x7BC7;&#x5206;&#x6790;&#x4E86;cache_t&#x7684;&#x7ED3;&#x6784;&#x548C;&#x600E;&#x4E48;&#x7F13;&#x5B58;&#x65B9;&#x6CD5;&#x7684;&#xFF0C;&#x8FD9;&#x91CC;&#x7EE7;&#x7EED;&#x5206;&#x6790;objc_class&#x4E2D;&#x7684;class_data_bits_t&#xFF0C;&#x641C;&#x7D22;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x4E3B;&#x8981;&#x7ED3;&#x6784;&#x5982;&#x4E0B;</p><pre><code>struct class_data_bits_t {
    friend objc_class;
    uintptr_t bits;

    class_rw_t* data() const {
        return (class_rw_t *)(bits &amp; FAST_DATA_MASK);
    }

    bool isAnySwift() {
        return isSwiftStable() || isSwiftLegacy();
    }
};
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x7ED3;&#x6784;&#x4F53;&#x91CC;&#x9762;&#x53EA;&#x6709;&#x4E00;&#x4E2A;bits&#xFF0C;&#x7136;&#x540E;&#x4E3B;&#x8981;&#x65B9;&#x6CD5;&#x5C31;&#x662F;&#x83B7;&#x53D6;class_rw_t&#xFF0C;&#x548C;&#x5224;&#x65AD;&#x662F;&#x4E0D;&#x662F;Swift&#x7684;&#x7C7B;&#x3002;</p><p>&#x770B;&#x6807;&#x9898;&#x5C31;&#x77E5;&#x9053;&#xFF0C;&#x8FD9;&#x7BC7;&#x6587;&#x7AE0;&#x7684;&#x91CD;&#x70B9;&#x5C31;&#x662F;class_rw_t&#xFF0C;&#x6E90;&#x7801;&#x4E2D;&#x641C;&#x7D22;&#x627E;&#x5230;&#x7ED3;&#x6784;&#x4F53;&#x5B9A;&#x4E49;</p><pre><code>struct class_rw_t {
    uint32_t flags; //&#x6807;&#x8BB0;&#x4F4D;
    uint16_t witness; //&#x5B58;&#x653E;cls&#x5730;&#x5740; &#x7F13;&#x5B58;range&#x7684;&#x7D22;&#x5F15;
    
    explicit_atomic&lt;uintptr_t&gt; ro_or_rw_ext;

    Class firstSubclass; //&#x7B2C;&#x4E00;&#x4E2A;&#x5B50;&#x7C7B;
    Class nextSiblingClass; //&#x5144;&#x5F1F;&#x7C7B;
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x4E3B;&#x8981;&#x5173;&#x6CE8;ro_or_rw_ext&#xFF0C;&#x4F7F;&#x7528;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4F1A;&#x901A;&#x8FC7;&#x8054;&#x5408;&#x6307;&#x9488;&#x8F6C;&#x6362;&#x6210;ro_or_rw_ext_t</p><pre><code>using ro_or_rw_ext_t = objc::PointerUnion&lt;const class_ro_t, class_rw_ext_t, PTRAUTH_STR(&quot;class_ro_t&quot;), PTRAUTH_STR(&quot;class_rw_ext_t&quot;)&gt;;

const ro_or_rw_ext_t get_ro_or_rwe() const {
    return ro_or_rw_ext_t{ro_or_rw_ext};
}

void set_ro_or_rwe(const class_ro_t *ro) {
    ro_or_rw_ext_t{ro, &amp;ro_or_rw_ext}.storeAt(ro_or_rw_ext, memory_order_relaxed);
}

void set_ro_or_rwe(class_rw_ext_t *rwe, const class_ro_t *ro) {
    // the release barrier is so that the class_rw_ext_t::ro initialization
    // is visible to lockless readers
    rwe-&gt;ro = ro;
    ro_or_rw_ext_t{rwe, &amp;ro_or_rw_ext}.storeAt(ro_or_rw_ext, memory_order_release);
}
</code></pre>
<p>&#x8FD9;&#x4E2A;&#x91CC;&#x9762;&#x53EF;&#x80FD;&#x5B58;&#x50A8;&#x7740;const class_ro_t&#x6216;&#x8005;class_rw_ext_t&#xFF0C;&#x4F46;&#x53EA;&#x6709;class_ro_t&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5C31;&#x5B58;&#x50A8;class_ro_t&#xFF0C;&#x5F53;&#x4E24;&#x8005;&#x540C;&#x65F6;&#x5B58;&#x5728;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5C31;&#x5B58;&#x50A8;class_rw_ext_t&#x3002;&#x4E5F;&#x5C31;&#x662F;&#x9700;&#x8981;&#x7684;&#x65F6;&#x5019;&#x624D;&#x4F1A;&#x52A0;&#x8F7D;class_rw_ext_t&#x8FDB;&#x884C;&#x5206;&#x914D;&#x5185;&#x5B58;&#x3002;</p><pre><code>class_rw_ext_t *extAllocIfNeeded() {
    auto v = get_ro_or_rwe();
    if (fastpath(v.is&lt;class_rw_ext_t *&gt;())) {
        return v.get&lt;class_rw_ext_t *&gt;(&amp;ro_or_rw_ext);
    } else {
        return extAlloc(v.get&lt;const class_ro_t *&gt;(&amp;ro_or_rw_ext));
    }
}

class_rw_ext_t *
class_rw_t::extAlloc(const class_ro_t *ro, bool deepCopy)
{
    runtimeLock.assertLocked();

    auto rwe = objc::zalloc&lt;class_rw_ext_t&gt;();

    rwe-&gt;version = (ro-&gt;flags &amp; RO_META) ? 7 : 0;

    method_list_t *list = ro-&gt;baseMethods();
    if (list) {
        if (deepCopy) list = list-&gt;duplicate();
        rwe-&gt;methods.attachLists(&amp;list, 1);
    }

    // See comments in objc_duplicateClass
    // property lists and protocol lists historically
    // have not been deep-copied
    //
    // This is probably wrong and ought to be fixed some day
    property_list_t *proplist = ro-&gt;baseProperties;
    if (proplist) {
        rwe-&gt;properties.attachLists(&amp;proplist, 1);
    }

    protocol_list_t *protolist = ro-&gt;baseProtocols;
    if (protolist) {
        rwe-&gt;protocols.attachLists(&amp;protolist, 1);
    }

    set_ro_or_rwe(rwe, ro);
    return rwe;
}
</code></pre>
<p>&#x641C;&#x7D22;extAllocIfNeeded&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x5728;&#x4EE5;&#x4E0B;&#x65B9;&#x6CD5;&#x4E2D;&#x8C03;&#x7528;</p><pre><code>static void
attachCategories(Class cls, const locstamped_category_t *cats_list, uint32_t cats_count,int flags)

BOOL class_addProtocol(Class cls, Protocol *protocol_gen)

static bool 
_class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attrs, unsigned int count, bool replace)
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x5F53;&#x7C7B;&#x7684;&#x65B9;&#x6CD5;&#x3001;&#x534F;&#x8BAE;&#x3001;&#x5C5E;&#x6027;&#xFF0C;&#x9664;&#x7C7B;&#x672C;&#x8EAB;&#x5916;&#x6709;&#x989D;&#x5916;&#x6DFB;&#x52A0;&#x7684;&#x65F6;&#x5019;&#x5C31;&#x4F1A;&#x52A0;&#x8F7D;class_rw_ext_t&#x5206;&#x914D;&#x5185;&#x5B58;&#x3002;</p><p>class_rw_ext_t &#x7ED3;&#x6784;&#x5982;&#x4E0B;</p><pre><code>struct class_rw_ext_t {
    DECLARE_AUTHED_PTR_TEMPLATE(class_ro_t)
    class_ro_t_authed_ptr&lt;const class_ro_t&gt; ro;
    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;
    char *demangledName;
    uint32_t version;
};
</code></pre>
<p>&#x8FD9;&#x91CC;&#x9762;&#x5B58;&#x50A8;&#x7740;&#xFF0C;*_array_t&#x7C7B;&#x578B;&#x7684;&#x65B9;&#x6CD5;&#x3001;&#x5C5E;&#x6027;&#x3001;&#x534F;&#x8BAE;&#x3002; </p><p>char *demangledName;&#xFF0C;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x5982;&#x4E0B;&#x65B9;&#x6CD5;&#xFF0C;&#x5E94;&#x8BE5;&#x662F;Swift&#x7C7B;OC&#x5316;&#x7684;&#x7C7B;&#x540D;&#x3002;</p><pre><code>const char *
protocol_t::demangledName() 
{
    if (!hasDemangledNameField())
        return mangledName;
    
    if (! _demangledName) {
        char *de = copySwiftV1DemangledName(mangledName, true/*isProtocol*/);
        if (! OSAtomicCompareAndSwapPtrBarrier(nil, (void*)(de ?: mangledName), 
                                               (void**)&amp;_demangledName)) 
        {
            if (de) free(de);
        }
    }
    return _demangledName;
}
</code></pre>
<p>version&#x5E94;&#x8BE5;&#x662F;&#x7248;&#x672C;&#xFF0C;&#x8FD9;&#x91CC;&#x5982;&#x679C;&#x662F;7&#x7684;&#x8BDD;&#x5F53;&#x524D;&#x7C7B;&#x4E3A;&#x5143;&#x7C7B;&#xFF0C;0&#x7684;&#x8BDD;&#x4E3A;&#x666E;&#x901A;&#x7C7B;</p><pre><code>rwe-&gt;version = (ro-&gt;flags &amp; RO_META) ? 7 : 0;
</code></pre>
<p>class_ro_t&#x7ED3;&#x6784;&#x5982;&#x4E0B;</p><pre><code>struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    union {
        const uint8_t * ivarLayout;
        Class nonMetaclass;
    };

    explicit_atomic&lt;const char *&gt; name;
    // With ptrauth, this is signed if it points to a small list, but
    // may be unsigned if it points to a big list.
    void *baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

    method_list_t *baseMethods() const {
#if __has_feature(ptrauth_calls)
        method_list_t *ptr = ptrauth_strip((method_list_t *)baseMethodList, ptrauth_key_method_list_pointer);
        if (ptr == nullptr)
            return nullptr;

        // Don&apos;t auth if the class_ro and the method list are both in the shared cache.
        // This is secure since they&apos;ll be read-only, and this allows the shared cache
        // to cut down on the number of signed pointers it has.
        bool roInSharedCache = objc::inSharedCache((uintptr_t)this);
        bool listInSharedCache = objc::inSharedCache((uintptr_t)ptr);
        if (roInSharedCache &amp;&amp; listInSharedCache)
            return ptr;

        // Auth all other small lists.
        if (ptr-&gt;isSmallList())
            ptr = ptrauth_auth_data((method_list_t *)baseMethodList,
                                    ptrauth_key_method_list_pointer,
                                    ptrauth_blend_discriminator(&amp;baseMethodList,
                                                                methodListPointerDiscriminator));
        return ptr;
#else
        return (method_list_t *)baseMethodList;
#endif
    }
};
</code></pre>
<p>&#x8FD9;&#x91CC;&#x9762;&#x4E3B;&#x8981;&#x5B58;&#x50A8;&#x7740;&#x7C7B;&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x5305;&#x542B;&#x5927;&#x5C0F;&#x3001;&#x7C7B;&#x540D;&#x3001;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x3001;&#x5C5E;&#x6027;&#x5217;&#x8868;&#x3001;&#x65B9;&#x6CD5;&#x5217;&#x8868;&#x3001;&#x534F;&#x8BAE;&#x7B49;&#x4FE1;&#x606F;&#x3002;&#x8FD8;&#x6709;&#x5C31;&#x662F;class_ro_t&#x662F;&#x53EA;&#x8BFB;&#x7684;&#xFF0C;&#x5B58;&#x50A8;&#x7684;&#x4FE1;&#x606F;&#x5728;&#x7F16;&#x8BD1;&#x65F6;&#x671F;&#x5C31;&#x5DF2;&#x7ECF;&#x786E;&#x5B9A;&#x4E86;&#xFF0C;&#x4E0D;&#x80FD;&#x518D;&#x66F4;&#x6539;&#xFF0C;&#x5E76;&#x4E14;&#x5FC5;&#x8981;&#x7684;&#x65F6;&#x5019;&#x53EF;&#x4EE5;&#x6E05;&#x9664;&#xFF0C;&#x9700;&#x8981;&#x7528;&#x7684;&#x65F6;&#x5019;&#x91CD;&#x78C1;&#x76D8;&#x4E2D;&#x52A0;&#x8F7D;&#x5C31;&#x597D;&#x4E86;&#x3002;</p><p>class_rw_t &#x662F;&#x53EF;&#x8BFB;&#x53EF;&#x5199;&#x7684;&#xFF0C;&#x5B83;&#x4FE1;&#x606F;&#x7684;&#x5B58;&#x50A8;&#x662F;&#x5728;&#x8FD0;&#x884C;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x9700;&#x8981;&#x7528;&#x5230;&#x7684;&#x65F6;&#x5019;&#x624D;&#x4F1A;&#x5199;&#x5165;&#xFF0C;&#x5E76;&#x4E14;&#x4E00;&#x76F4;&#x5B58;&#x5728;&#x4E8E;&#x5185;&#x5B58;&#x4E2D;&#x3002;&#x56E0;&#x4E3A;class_rw_ext_t&#x6CA1;&#x6709;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x5217;&#x8868;&#xFF0C;&#x8FD9;&#x5C31;&#x662F;&#x4E3A;&#x4EC0;&#x4E48;&#x5206;&#x7C7B;&#x4E2D;&#x4E0D;&#x80FD;&#x6DFB;&#x52A0;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x7684;&#x539F;&#x56E0;&#x3002;</p><p>&#x7EE7;&#x7EED;&#x770B;&#x4E0B; *_array_t &#x548C; *_list_t&#xFF0C;&#x67E5;&#x627E;&#x4EE3;&#x7801;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x5982;&#x4E0B;&#x4EE3;&#x7801;</p><pre><code>class *_array_t : public list_array_tt&lt;*_t, *_list_t, *_list_t_authed_ptr&gt;
</code></pre>
<p>*_array_t &#x7EE7;&#x627F;&#x4E8E;list_array_tt&#xFF0C;&#x91CC;&#x9762;&#x5B58;&#x653E;&#x7740;*_list_t&#x3002;&#x76F8;&#x5F53;&#x4E8E;&#x4E00;&#x4E2A;&#x4E8C;&#x7EF4;&#x6570;&#x7EC4;&#xFF0C;&#x7ED3;&#x6784;&#x5982;&#x4E0B;</p><pre><code>class list_array_tt {
    struct array_t {
        uint32_t count;
        Ptr&lt;List&gt; lists[0];

        static size_t byteSize(uint32_t count) {
            return sizeof(array_t) + count*sizeof(lists[0]);
        }
        size_t byteSize() {
            return byteSize(count);
        }
    };
}
</code></pre>
<p>*_list_t&#x91CC;&#x9762;&#x5B58;&#x50A8;&#x7740;&#x5404;&#x81EA;&#x7684;*_t&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x5206;&#x522B;&#x5305;&#x542B;&#x5404;&#x81EA;&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x5217;&#x5982;method_t&#xFF08;&#x7B80;&#x5316;&#xFF09;</p><pre><code>struct method_t {
    //&#x2026;
    struct big {
        SEL name;
        const char *types;
        MethodListIMP imp;
    };
    //&#x2026;
}
</code></pre>
<p>&#x5176;&#x4ED6;&#x66F4;&#x591A;&#x8BF7;&#x67E5;&#x770B;&#x6E90;&#x7801;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x8D34;&#x4EE3;&#x7801;&#x4E86;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[Objective-C类结构分析(cache_t)]]></title><description><![CDATA[<p>&#x5728;Objective-C&#x4E2D;Class&#x5E95;&#x5C42;&#x5B9E;&#x73B0;&#x5176;&#x5B9E;&#x662F;&#x4E00;&#x4E2A;objc_class&#x7C7B;&#x578B;&#x7684;&#x7ED3;&#x6784;&#x4F53;</p><pre><code>/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
</code></pre>
<p>&#x67E5;&#x770B;&#x6E90;&#x7801;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x5230;objc_class&#x7684;&#x7ED3;&#x6784;&#x5982;&#x4E0B;</p>]]></description><link>https://lemonlie.com/objective-c-lei-jie-gou-fen-xi-cache/</link><guid isPermaLink="false">65672ee96c00b44e3076578e</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Wed, 15 Jun 2022 11:52:30 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1526649661456-89c7ed4d00b8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDQwfHxjb2RlfGVufDB8fHx8MTcwMTI2OTE1OHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1526649661456-89c7ed4d00b8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDQwfHxjb2RlfGVufDB8fHx8MTcwMTI2OTE1OHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Objective-C&#x7C7B;&#x7ED3;&#x6784;&#x5206;&#x6790;(cache_t)"><p>&#x5728;Objective-C&#x4E2D;Class&#x5E95;&#x5C42;&#x5B9E;&#x73B0;&#x5176;&#x5B9E;&#x662F;&#x4E00;&#x4E2A;objc_class&#x7C7B;&#x578B;&#x7684;&#x7ED3;&#x6784;&#x4F53;</p><pre><code>/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
</code></pre>
<p>&#x67E5;&#x770B;&#x6E90;&#x7801;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x5230;objc_class&#x7684;&#x7ED3;&#x6784;&#x5982;&#x4E0B;</p><pre><code>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
}
</code></pre>
<p>objc_class&#x7EE7;&#x627F;&#x4E8E;objc_object&#x7ED3;&#x6784;&#x4F53;&#xFF0C;objc_object&#x91CC;&#x9762;&#x53EA;&#x6709;&#x4E2A;isa_t isa&#x6307;&#x9488;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x518D;&#x5206;&#x6790;&#xFF0C;&#x60F3;&#x4E86;&#x89E3;&#x66F4;&#x591A;&#x53EF;&#x4EE5;&#x770B;&#x5F80;&#x671F;&#x5185;&#x5BB9;&#x3002;</p><p>&#x9664;&#x4E86;isa&#x6307;&#x9488;&#x5916;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8FD8;&#x6709;&#x4E2A;Class&#x7C7B;&#x578B;&#x7684;superclass&#xFF0C;&#x5F88;&#x660E;&#x663E;&#x8FD9;&#x4E2A;&#x662F;&#x6307;&#x5411;&#x7236;&#x7C7B;&#x7684;&#x6307;&#x9488;&#x3002;</p><p>&#x7136;&#x540E;&#x5C31;&#x662F;cache_t&#x7C7B;&#x578B;&#x7684;cache&#xFF0C;&#x4ECE;&#x6E90;&#x7801;&#x4E2D;&#x67E5;&#x627E;&#x5176;&#x7ED3;&#x6784;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x63D0;&#x53D6;&#x9700;&#x8981;&#x7684;&#x90E8;&#x5206;&#x3002;&#x7136;&#x540E;&#x53C8;&#x53D1;&#x73B0;CACHE_MASK_STORAGE&#x5B8F;&#x5BF9;&#x5E94;&#x7684;&#x4E0D;&#x540C;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x641C;&#x7D22;&#x5B8F;CACHE_MASK_STORAGE&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x5982;&#x4E0B;</p><pre><code>#if defined(__arm64__) &amp;&amp; __LP64__
    #if TARGET_OS_OSX || TARGET_OS_SIMULATOR
    #define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_HIGH_16_BIG_ADDRS
    #else
    #define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_HIGH_16
    #endif
#elif defined(__arm64__) &amp;&amp; !__LP64__
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_LOW_4
#else
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_OUTLINED
#endif
</code></pre>
<p>&#x53EF;&#x5F97;&#x53EA;&#x6709;CACHE_MASK_STORAGE==CACHE_MASK_STORAGE_HIGH_16&#x7684;&#x65F6;&#x5019;&#x624D;&#x662F;&#x9700;&#x8981;&#x7684;&#x90E8;&#x5206;&#xFF0C;&#x53EF;&#x4EE5;&#x7B80;&#x5316;cache_t&#x7ED3;&#x6784;&#x5982;&#x4E0B;</p><pre><code>struct cache_t {
    explicit_atomic&lt;uintptr_t&gt; _bucketsAndMaybeMask;
    union {
        struct {
            explicit_atomic&lt;mask_t&gt;    _maybeMask;
#if __LP64__
            uint16_t                   _flags;
#endif
            uint16_t                   _occupied;
        };
        explicit_atomic&lt;preopt_cache_t *&gt; _originalPreoptCache;
    };

    // _bucketsAndMaybeMask is a buckets_t pointer in the low 48 bits
    // _maybeMask is unused, the mask is stored in the top 16 bits.
};
</code></pre>
<p>&#x770B;&#x6CE8;&#x91CA;&#xFF0C;_bucketsAndMaybeMask&#x662F;&#x4E00;&#x4E2A;&#x4F4E;48&#x4F4D;&#x5B58;&#x50A8;&#x7740;buckets_t&#x7684;&#x6307;&#x9488;&#xFF0C;_maybeMask&#x5728;&#x5F53;&#x524D;&#x67B6;&#x6784;&#x4E0B;unused&#xFF0C;mask&#x5B58;&#x5728;&#x4E86;_bucketsAndMaybeMask&#x9AD8;16&#x4F4D;&#x91CC;&#x9762;&#x3002;</p><p>&#x641C;&#x7D22;flags&#xFF0C;&#x53D1;&#x73B0;&#x53C2;&#x4E0E;FAST_CACHE_ALLOC_MASK&#x4F4D;&#x8FD0;&#x7B97;&#xFF0C;&#x5E94;&#x8BE5;FAST CACHE&#x6807;&#x5FD7;&#x4F4D;</p><p>&#x641C;&#x7D22;_occupied&#xFF0C;&#x53D1;&#x73B0;&#x5728;setBucketsAndMask&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x88AB;&#x8D4B;&#x503C;0&#xFF0C;&#x5728;cache_t::insert&#x65B9;&#x6CD5;&#x4E2D;&#x627E;&#x5230;&#x8C03;&#x7528;&#x4E86; _occupied++&#xFF0C;insert&#x662F;&#x63D2;&#x5165;&#x65B0;&#x65B9;&#x6CD5;&#x7F13;&#x5B58;&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x4E2A;&#x503C;&#x5E94;&#x8BE5;&#x4E3A;&#x5F53;&#x524D;cache&#x5DF2;&#x5B58;&#x50A8;&#x7F13;&#x5B58;&#x65B9;&#x6CD5;&#x7684;&#x6570;&#x91CF;&#x3002;</p><p>&#x65B9;&#x6CD5;&#x6700;&#x7EC8;&#x662F;&#x5B58;&#x50A8;&#x5728;bucket_t&#x4E2D;&#x7684;&#xFF0C;&#x5148;&#x770B;&#x4E0B;&#x662F;&#x600E;&#x4E48;&#x5B58;&#x50A8;&#x7684;&#xFF0C;&#x641C;&#x7D22;&#x627E;&#x5230;&#x5982;&#x4E0B;&#x7ED3;&#x6784;&#x4F53;</p><pre><code>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__
    explicit_atomic&lt;uintptr_t&gt; _imp;
    explicit_atomic&lt;SEL&gt; _sel;
#else
    explicit_atomic&lt;SEL&gt; _sel;
    explicit_atomic&lt;uintptr_t&gt; _imp;
#endif
};
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x5B58;&#x653E;&#x65B9;&#x6CD5;&#x6307;&#x9488;&#x548C;&#x65B9;&#x6CD5;&#x540D;&#x7684;&#x7ED3;&#x6784;&#x4F53;&#xFF0C;&#x9700;&#x8981;&#x6CE8;&#x610F;&#x7684;&#x662F;&#xFF0C;arm64&#x67B6;&#x6784;&#x4E0B;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x5728;&#x524D;&#x65B9;&#x6CD5;&#x540D;&#x5728;&#x540E;&#x3002;</p><p>SEL _sel&#x4E3A;&#x4EC0;&#x4E48;&#x662F;&#x65B9;&#x6CD5;&#x540D;&#x5B57;&#xFF1F;&#x641C;&#x7D22;SEL&#x53EF;&#x5F97;&#xFF0C;SEL &#x662F;&#x4E00;&#x4E2A;struct<strong> </strong>objc_selector&#x7684;&#x6307;&#x9488;</p><pre><code>/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;
</code></pre>
<p>&#x7136;&#x540E;&#x5199;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x6D4B;&#x8BD5;&#x4E0B;</p><pre><code>SEL sel = @selector(run);
NSLog(@&quot;%s&quot;,sel);
</code></pre>
<p>&#x8FD0;&#x884C;&#x540E;&#x8F93;&#x51FA;&#x7ED3;&#x679C;&#x5982;&#x4E0B;&#x56FE;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-14-at-21.55.20.png" class="kg-image" alt="Objective-C&#x7C7B;&#x7ED3;&#x6784;&#x5206;&#x6790;(cache_t)" loading="lazy" width="954" height="462" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-14-at-21.55.20.png 600w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-14-at-21.55.20.png 954w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;_sel&#x662F;&#x6307;&#x5411;&#x65B9;&#x6CD5;&#x540D;&#x7684;&#x6307;&#x9488;&#x3002;</p><p><strong>void</strong> bucket_t::set(bucket_t *base, <strong>SEL</strong> newSel, <strong>IMP</strong> newImp, Class cls)&#x65B9;&#x6CD5;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x5177;&#x4F53;&#x5199;&#x5165;&#x8FC7;&#x7A0B;</p><pre><code>template&lt;Atomicity atomicity, IMPEncoding impEncoding&gt;
void bucket_t::set(bucket_t *base, SEL newSel, IMP newImp, Class cls)
{
    uintptr_t encodedImp = (impEncoding == Encoded
                            ? encodeImp(base, newImp, newSel, cls)
                            : (uintptr_t)newImp);

    // LDP/STP guarantees that all observers get
    // either imp/sel or newImp/newSel
    stp(encodedImp, (uintptr_t)newSel, this);
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;stp&#x5199;&#x5165;&#x7684;&#x662F;&#x65B9;&#x6CD5;&#x540D;&#x548C;&#x52A0;&#x5BC6;&#x540E;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x4EE5;&#x627E;&#x5230;stp&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x5982;&#x4E0B;</p><pre><code>stp(uintptr_t onep, uintptr_t twop, void *destp)
{
    __asm__ (&quot;stp %&quot; p &quot;[one], %&quot; p &quot;[two], [%x[dest]]&quot;
             : &quot;=m&quot; (((uintptr_t *)(destp))[0]),
               &quot;=m&quot; (((uintptr_t *)(destp))[1])
             : [one] &quot;r&quot; (onep),
               [two] &quot;r&quot; (twop),
               [dest] &quot;r&quot; (destp)
             : /* no clobbers */
             );
}
</code></pre>
<p>&#x901A;&#x8FC7;&#x6C47;&#x7F16;&#x628A;&#x4E24;&#x4E2A;&#x503C;&#x5199;&#x5165;&#x5230;bucket_t&#x91CC;&#x9762;&#xFF0C;&#x52A0;&#x5FEB;&#x4E86;&#x5199;&#x5165;&#x901F;&#x5EA6;&#x3002;</p><p>&#x5206;&#x6790;&#x5B8C;&#x65B9;&#x6CD5;&#x65F6;&#x5982;&#x4F55;&#x5199;&#x5165;&#x7684;&#xFF0C;&#x7EE7;&#x7EED;&#x770B;bucket_t&#x662F;&#x600E;&#x4E48;&#x5199;&#x5165;&#x7684;&#x3002;&#x5728;objc-cache.mm&#x6587;&#x4EF6;&#x4E2D;&#x641C;&#x7D22;.set&#x627E;&#x5230;<strong>void</strong> cache_t::insert(<strong>SEL</strong> sel, <strong>IMP</strong> imp, <strong>id</strong> receiver)&#x65B9;&#x6CD5;&#xFF0C;&#x7B80;&#x5316;&#x540E;&#x4EE3;&#x7801;&#x5982;&#x4E0B;</p><pre><code>void cache_t::insert(SEL sel, IMP imp, id receiver)
{
    mask_t newOccupied = occupied() + 1;
    unsigned oldCapacity = capacity(), capacity = oldCapacity;
    if (slowpath(isConstantEmptyCache())) {
        // Cache is read-only. Replace it.
        if (!capacity) capacity = INIT_CACHE_SIZE;
        reallocate(oldCapacity, capacity, /* freeOld */false);
    }
    else if (fastpath(newOccupied + CACHE_END_MARKER &lt;= cache_fill_ratio(capacity))) {
        // Cache is less than 3/4 or 7/8 full. Use it as-is.
    }
#if CACHE_ALLOW_FULL_UTILIZATION
    else if (capacity &lt;= FULL_UTILIZATION_CACHE_SIZE &amp;&amp; newOccupied + CACHE_END_MARKER &lt;= capacity) {
        // Allow 100% cache utilization for small buckets. Use it as-is.
    }
#endif
    else {
        capacity = capacity ? capacity * 2 : INIT_CACHE_SIZE;
        if (capacity &gt; MAX_CACHE_SIZE) {
            capacity = MAX_CACHE_SIZE;
        }
        reallocate(oldCapacity, capacity, true);
    }

    bucket_t *b = buckets();
    mask_t m = capacity - 1;
    mask_t begin = cache_hash(sel, m);
    mask_t i = begin;

    // Scan for the first unused slot and insert there.
    // There is guaranteed to be an empty slot.
    do {
        if (fastpath(b[i].sel() == 0)) {
            incrementOccupied();
            b[i].set&lt;Atomic, Encoded&gt;(b, sel, imp, cls());
            return;
        }
        if (b[i].sel() == sel) {
            // The entry was added to the cache by some other thread
            // before we grabbed the cacheUpdateLock.
            return;
        }
    } while (fastpath((i = cache_next(i, m)) != begin));

    bad_cache(receiver, (SEL)sel);
}
</code></pre>
<p>&#x5148;&#x83B7;&#x53D6;capacity&#xFF0C;&#x641C;&#x7D22;capacity()&#x65B9;&#x6CD5;&#xFF0C;&#x53D1;&#x73B0;capacity = mask() + 1</p><pre><code>unsigned cache_t::capacity() const
{
    return mask() ? mask()+1 : 0; 
}
</code></pre>
<p>&#x7EE7;&#x7EED;&#x641C;&#x7D22;&#x627E;&#x5230;mask&#x7684;&#x8D4B;&#x503C;&#x548C;&#x53D6;&#x503C;&#x8FC7;&#x7A0B;</p><pre><code>void cache_t::setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask)
{
    uintptr_t buckets = (uintptr_t)newBuckets;
    uintptr_t mask = (uintptr_t)newMask;

    ASSERT(buckets &lt;= bucketsMask);
    ASSERT(mask &lt;= maxMask);

    _bucketsAndMaybeMask.store(((uintptr_t)newMask &lt;&lt; maskShift) | (uintptr_t)newBuckets, memory_order_relaxed);
    _occupied = 0;
}

mask_t cache_t::mask() const
{
    uintptr_t maskAndBuckets = _bucketsAndMaybeMask.load(memory_order_relaxed);
    return maskAndBuckets &gt;&gt; maskShift;
}
</code></pre>
<p>&#x641C;&#x7D22;setBucketsAndMask&#xFF0C;&#x53EF;&#x4EE5;&#x627E;&#x5230;</p><pre><code>void cache_t::reallocate(mask_t oldCapacity, mask_t newCapacity, bool freeOld)
{
    bucket_t *oldBuckets = buckets();
    bucket_t *newBuckets = allocateBuckets(newCapacity);

    // Cache&apos;s old contents are not propagated. 
    // This is thought to save cache memory at the cost of extra cache fills.
    // fixme re-measure this

    ASSERT(newCapacity &gt; 0);
    ASSERT((uintptr_t)(mask_t)(newCapacity-1) == newCapacity-1);

    setBucketsAndMask(newBuckets, newCapacity - 1);
    
    if (freeOld) {
        collect_free(oldBuckets, oldCapacity);
    }
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x5F97;&#x51FA;capacity&#x662F;buckets&#x7684;&#x957F;&#x5EA6;&#xFF0C;mask&#x662F;capacity-1&#x3002;</p><p>&#x7EE7;&#x7EED;&#x5206;&#x6790;insert&#x65B9;&#x6CD5;&#xFF0C;</p><p>&#x7B2C;&#x4E00;&#x4E2A;if&#x662F;&#x5F53;cache&#x4E3A;&#x7A7A;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x521D;&#x59CB;&#x5316;buckets&#x3002;</p><p>&#x7B2C;&#x4E8C;&#x4E2A;&#x548C;&#x7B2C;&#x4E09;&#x4E2A;if&#x5206;&#x522B;&#x662F;&#x65B0;&#x7684;&#x957F;&#x5EA6;&#x5C0F;&#x4E8E;&#x7B49;&#x4E8E;&#x5BB9;&#x5668;&#x7684;3/4&#x6216;&#x8005;&#x5C0F;&#x4E8E;&#x7B49;&#x4E8E;&#x5BB9;&#x5668;&#x7684;&#x5927;&#x5C0F;&#x7684;&#x65F6;&#x5019;&#x4EC0;&#x4E48;&#x4E5F;&#x4E0D;&#x505A;&#x3002;</p><p>&#x7B2C;&#x56DB;&#x4E2A;&#x662F;&#x65B0;&#x7684;&#x957F;&#x5EA6;&#x5927;&#x4E8E;&#x5BB9;&#x5668;&#x7684;&#x957F;&#x5EA6;&#x65F6;&#xFF0C;&#x4EE5;2&#x500D;&#x7684;capacity&#x6269;&#x5BB9;&#xFF0C;&#x5E76;&#x4E14;&#x91CA;&#x653E;&#x4E4B;&#x524D;&#x7684;buckets&#x3002;</p><p>&#x5728;&#x4E0B;&#x9762;&#x5C31;&#x662F;&#x63D2;&#x5165;&#x903B;&#x8F91;&#xFF0C;&#x901A;&#x8FC7;buckets()&#x83B7;&#x53D6;bucket_t &#x6570;&#x7EC4;&#x6307;&#x9488;&#xFF0C;&#x901A;&#x8FC7;&#x957F;&#x5EA6;&#x51CF;1&#x83B7;&#x53D6;mask&#xFF0C;&#x518D;&#x901A;&#x8FC7;sel&#x548C;mask&#x7B97;&#x51FA;&#x63D2;&#x5165;&#x7684;&#x7D22;&#x5F15;&#x3002;</p><pre><code>static inline mask_t cache_hash(SEL sel, mask_t mask) 
{
    uintptr_t value = (uintptr_t)sel;
#if CONFIG_USE_PREOPT_CACHES
    value ^= value &gt;&gt; 7;
#endif
    return (mask_t)(value &amp; mask);
}
</code></pre>
<p>do while&#x662F;&#x63D2;&#x5165;&#x65B9;&#x6CD5;&#x3002;&#x5982;&#x679C;&#xFF0C;&#x5F53;&#x524D;&#x7D22;&#x5F15;&#x4E0B;&#x7684;bucket&#x6CA1;&#x6709;&#x88AB;&#x4F7F;&#x7528;&#x6216;&#x8005;&#x662F;&#x5F53;&#x524D;&#x5B58;&#x5165;&#x7684;&#x65B9;&#x6CD5;&#x548C;&#x8981;&#x5B58;&#x5165;&#x7684;&#x65B9;&#x6CD5;&#x4E00;&#x6837;&#x7684;&#x8BDD;&#x5C31;&#x4F1A;&#x8FD4;&#x56DE;&#x3002;&#x5982;&#x679C;&#x6709;&#x503C;&#x4E14;&#x4E0D;&#x4E00;&#x6837;&#x7684;&#x8BDD;&#xFF0C;&#x8BA1;&#x7B97;&#x65B0;&#x7684;&#x7D22;&#x5F15;&#x7EE7;&#x7EED;&#x63D2;&#x5165;&#x3002;&#x5177;&#x4F53;&#x7D22;&#x5F15;&#x7B97;&#x6CD5;&#x5982;&#x4E0B;</p><pre><code>static inline mask_t cache_next(mask_t i, mask_t mask) {
    return i ? i-1 : mask;
}
</code></pre>
<p>&#x6700;&#x540E;&#x5C31;&#x662F;&#xFF0C;&#x904D;&#x5386;&#x5B8C;buckets&#xFF0C;&#x65B9;&#x6CD5;&#x4F9D;&#x65E7;&#x6CA1;&#x80FD;&#x63D2;&#x5165;&#x6210;&#x529F;&#xFF0C;&#x5C31;&#x4F1A;Crash&#x3002;</p><p>&#x7EFC;&#x4E0A;&#xFF0C;cache_t&#x91CC;&#x9762;&#x6709;&#x4E2A;&#x6563;&#x5217;&#x8868;buckets&#xFF0C;buckets&#x91CC;&#x9762;&#x5B58;&#x50A8;bucket_t&#xFF0C;bucket_t&#x91CC;&#x9762;&#x5B58;&#x50A8;&#x7740;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x548C;&#x65B9;&#x6CD5;&#x540D;&#x3002;&#x65B9;&#x6CD5;&#x5B58;&#x5165;buckets&#x7684;&#x7D22;&#x5F15;&#x662F;&#x4EE5;sel&#x548C;mask&#x7B97;&#x51FA;&#x7684;&#x3002;&#x5982;&#x679C;&#x5B58;&#x5165;&#x7684;&#x65B9;&#x6CD5;&#x5927;&#x4E8E;buckets&#x7684;&#x957F;&#x5EA6;&#x540E;&#xFF0C;&#x4F1A;&#x4EE5;2&#x500D;&#x7684;&#x957F;&#x5EA6;&#x6269;&#x5BB9;&#x4E00;&#x4E2A;&#x65B0;&#x7684;buckets&#xFF0C;&#x7136;&#x540E;&#x91CA;&#x653E;&#x65E7;&#x7684;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[Tagged Pointer 详解]]></title><description><![CDATA[<p>Tagged Pointer&#x662F;&#x82F9;&#x679C;&#x5728;64bit&#x8BBE;&#x5907;&#x5F15;&#x5165;&#x7684;&#x4E00;&#x79CD;&#x6280;&#x672F;&#xFF0C;&#x662F;&#x7528;&#x4E8E;&#x4F18;&#x5316;NSNumber&#x3001;NSDate&#x3001;NSString&#x7B49;&#x5C0F;&#x5BF9;&#x8C61;&#x7684;&#x5B58;&#x50A8;&#x3002;</p><p>&#x67E5;&#x770B;objc4&#x6E90;&#x7801;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x53EA;&#x8981;64&#x4F4D;&#x7CFB;&#x7EDF;</p>]]></description><link>https://lemonlie.com/tagged-pointer-xiang-jie/</link><guid isPermaLink="false">65672ee96c00b44e3076578d</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Mon, 13 Jun 2022 09:42:44 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1557599443-2071a2df9c19?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDI5fHxjb2RlfGVufDB8fHx8MTY1NTExMzMxOQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1557599443-2071a2df9c19?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDI5fHxjb2RlfGVufDB8fHx8MTY1NTExMzMxOQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Tagged Pointer &#x8BE6;&#x89E3;"><p>Tagged Pointer&#x662F;&#x82F9;&#x679C;&#x5728;64bit&#x8BBE;&#x5907;&#x5F15;&#x5165;&#x7684;&#x4E00;&#x79CD;&#x6280;&#x672F;&#xFF0C;&#x662F;&#x7528;&#x4E8E;&#x4F18;&#x5316;NSNumber&#x3001;NSDate&#x3001;NSString&#x7B49;&#x5C0F;&#x5BF9;&#x8C61;&#x7684;&#x5B58;&#x50A8;&#x3002;</p><p>&#x67E5;&#x770B;objc4&#x6E90;&#x7801;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x53EA;&#x8981;64&#x4F4D;&#x7CFB;&#x7EDF;&#x624D;&#x652F;&#x6301;</p><!--kg-card-begin: markdown--><pre><code>#if __LP64__  //&#x6587;&#x4EF6;objc-internal.h line 283
#define OBJC_HAVE_TAGGED_POINTERS 1
#endif
</code></pre>
<!--kg-card-end: markdown--><p>&#x540C;&#x65F6;&#x4E5F;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#xFF0C;Tagged Pointer &#x6240;&#x652F;&#x6301;&#x7684;&#x7C7B;&#x578B;&#xFF0C;&#x4E00;&#x4E2A;objc_tag_index_t&#x7C7B;&#x578B;&#x7684;&#x679A;&#x4E3E;&#xFF0C;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>    // 60-bit payloads
    OBJC_TAG_NSAtom            = 0, 
    OBJC_TAG_1                 = 1, 
    OBJC_TAG_NSString          = 2, 
    OBJC_TAG_NSNumber          = 3, 
    OBJC_TAG_NSIndexPath       = 4, 
    OBJC_TAG_NSManagedObjectID = 5, 
    OBJC_TAG_NSDate            = 6,

    // 60-bit reserved
    OBJC_TAG_RESERVED_7        = 7, 

    // 52-bit payloads
    OBJC_TAG_Photos_1          = 8,
    OBJC_TAG_Photos_2          = 9,
    OBJC_TAG_Photos_3          = 10,
    OBJC_TAG_Photos_4          = 11,
    OBJC_TAG_XPC_1             = 12,
    OBJC_TAG_XPC_2             = 13,
    OBJC_TAG_XPC_3             = 14,
    OBJC_TAG_XPC_4             = 15,
    OBJC_TAG_NSColor           = 16,
    OBJC_TAG_UIColor           = 17,
    OBJC_TAG_CGColor           = 18,
    OBJC_TAG_NSIndexSet        = 19,
    OBJC_TAG_NSMethodSignature = 20,
    OBJC_TAG_UTTypeRecord      = 21,
</code></pre>
<!--kg-card-end: markdown--><p>ARM64&#x4F4D;&#x7684;&#x8BBE;&#x5907;&#xFF0C;tags&#x5728;&#x6700;&#x4F4E;&#x4F4D;&#xFF0C;&#x6269;&#x5C55;&#x7684;tags&#x5728;&#x6700;&#x9AD8;&#x4F4D;&#x3002;64&#x4F4D;&#x7684;Mac&#xFF0C;tags&#x5B58;&#x50A8;&#x5728;LSB&#xFF08;Least Significant Bit &#x6700;&#x4F4E;&#x4F4D;&#xFF09;&#x3002;&#x5176;&#x5B83;&#x60C5;&#x51B5;&#x6BD4;&#x5982;&#x6A21;&#x62DF;&#x5668;&#x548C;32&#x4F4D;&#x7684;&#x771F;&#x673A;&#xFF0C;tag&#x5B58;&#x50A8;&#x5728;MSB&#xFF08;Most Significant Bit &#x6700;&#x9AD8;&#x4F4D;&#xFF09;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>#if __arm64__
// ARM64 uses a new tagged pointer scheme where normal tags are in
// the low bits, extended tags are in the high bits, and half of the
// extended tag space is reserved for unobfuscated payloads.
#   define OBJC_SPLIT_TAGGED_POINTERS 1
#else
#   define OBJC_SPLIT_TAGGED_POINTERS 0
#endif

#if (TARGET_OS_OSX || TARGET_OS_MACCATALYST) &amp;&amp; __x86_64__
    // 64-bit Mac - tag bit is LSB
#   define OBJC_MSB_TAGGED_POINTERS 0
#else
    // Everything else - tag bit is MSB
#   define OBJC_MSB_TAGGED_POINTERS 1
#endif
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x91CC;&#x4E3B;&#x8981;&#x5199;&#x4E0B;ARM64&#x4F4D;&#x4E0B;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x5176;&#x4ED6;&#x7684;&#x5982;&#x679C;&#x611F;&#x5174;&#x8DA3;&#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x6E90;&#x7801;&#x3002;&#x5199;&#x4E4B;&#x524D;&#xFF0C;&#x5148;&#x65B0;&#x5EFA;&#x4E2A;iOS&#x5DE5;&#x7A0B;&#xFF0C;&#x7136;&#x540E;&#x5199;&#x5165;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#xFF0C;&#x5E76;&#x5728;&#x6700;&#x540E;&#x4EE5;&#x540E;&#x6253;&#x4E0A;&#x65AD;&#x70B9;&#xFF0C;&#x7136;&#x540E;&#x8FD0;&#x884C;</p><!--kg-card-begin: markdown--><pre><code>NSString *str1 = @&quot;a&quot;;
NSString *str2 = [NSString stringWithFormat:@&quot;a&quot;];
NSLog(@&quot;%@ %p %@&quot;,str1, str1, str1.class);
NSLog(@&quot;%@ %p %@&quot;,str2, str2, str2.class);
NSLog(@&quot;END&quot;);
</code></pre>
<!--kg-card-end: markdown--><p>&#x7136;&#x540E;&#x4F1A;&#x770B;&#x5230;&#x5982;&#x4E0B;&#x8F93;&#x51FA;&#x7ED3;&#x679C;&#xFF0C;&#x5E76;&#x4E14;&#x4F1A;&#x8FDB;&#x5165;&#x8C03;&#x8BD5;&#x72B6;&#x6001;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-00.56.15.png" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1518" height="104" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-13-at-00.56.15.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/Screen-Shot-2022-06-13-at-00.56.15.png 1000w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-00.56.15.png 1518w" sizes="(min-width: 720px) 720px"></figure><p>str2&#x7684;Class &#x662F;NSTaggedPointerString&#xFF0C;&#x786E;&#x5B9E;&#x662F;TaggedPoint&#xFF0C;&#x4F46;&#x662F;&#x5185;&#x5B58;&#x5730;&#x5740;&#x5F88;&#x5927;&#xFF0C;&#x5E76;&#x770B;&#x4E0D;&#x51FA;&#x6765;&#x6570;&#x636E;&#x662F;&#x600E;&#x4E48;&#x5B58;&#x50A8;&#x7684;&#x3002;</p><p>&#x7136;&#x540E;&#x6253;&#x5F00;Xcode&#x7684;&#x5185;&#x5B58;&#x67E5;&#x770B;&#x7A97;&#x53E3;&#xFF0C;&#x8DEF;&#x5F84;Debug-&gt;Debug Workflow-&gt;View Memory&#x5982;&#x4E0B;&#x56FE;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-00.58.50.png" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="2000" height="783" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-13-at-00.58.50.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/Screen-Shot-2022-06-13-at-00.58.50.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/Screen-Shot-2022-06-13-at-00.58.50.png 1600w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-00.58.50.png 2114w" sizes="(min-width: 720px) 720px"></figure><p>&#x5E76;&#x5728;&#x6253;&#x5F00;&#x7A97;&#x53E3;&#x7684;&#x6700;&#x4E0B;&#x65B9;Address&#x91CC;&#x9762;&#x641C;&#x7D22;&#x4E24;&#x4E2A;&#x5185;&#x5B58;&#x5730;&#x5740;&#xFF0C;str2&#x7684;&#x5730;&#x5740;&#x786E;&#x5B9E;&#x662F;&#x641C;&#x7D22;&#x4E0D;&#x5230;&#x7684;&#xFF0C;&#x8BC1;&#x660E;&#x8FD9;&#x4E2A;&#x6307;&#x9488;&#x5E76;&#x6CA1;&#x6709;&#x6307;&#x5411;&#x4EFB;&#x4F55;&#x5185;&#x5B58;&#x3002;</p><p>&#x8FD9;&#x4E2A;&#x5730;&#x5740;&#x662F;&#x600E;&#x4E48;&#x751F;&#x6210;&#x7684;&#x5462;&#xFF1F;&#x8FD9;&#x65F6;&#x5019;&#x9700;&#x8981;&#x4ECE;&#x6E90;&#x7801;&#x4E2D;&#x5BFB;&#x627E;&#x7B54;&#x6848;&#x4E86;&#x3002;&#x5728;&#x6E90;&#x7801;&#x4E2D;&#x641C;&#x7D22;TaggedPoint&#xFF0C;&#x627E;&#x5230;&#x4E00;&#x4E2A;_objc_makeTaggedPointer&#x7684;&#x65B9;&#x6CD5;</p><!--kg-card-begin: markdown--><pre><code>static inline void * _Nonnull
_objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value)
{
    if (tag &lt;= OBJC_TAG_Last60BitPayload) {
        uintptr_t result =
            (_OBJC_TAG_MASK | 
             ((uintptr_t)tag &lt;&lt; _OBJC_TAG_INDEX_SHIFT) | 
             ((value &lt;&lt; _OBJC_TAG_PAYLOAD_RSHIFT) &gt;&gt; _OBJC_TAG_PAYLOAD_LSHIFT));
        return _objc_encodeTaggedPointer(result);
    } else {
        uintptr_t result =
            (_OBJC_TAG_EXT_MASK |
             ((uintptr_t)(tag - OBJC_TAG_First52BitPayload) &lt;&lt; _OBJC_TAG_EXT_INDEX_SHIFT) |
             ((value &lt;&lt; _OBJC_TAG_EXT_PAYLOAD_RSHIFT) &gt;&gt; _OBJC_TAG_EXT_PAYLOAD_LSHIFT));
        return _objc_encodeTaggedPointer(result);
    }
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x533A;&#x5206;&#x4E86;60&#x4F4D;playload&#x548C;52&#x4F4D;payload&#x3002;&#x70B9;objc_tag_index_t&#x8FDB;&#x53BB;&#x770B;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>    OBJC_TAG_Last60BitPayload  = 6, 
    OBJC_TAG_First52BitPayload = 8, 
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x91CC;&#x5148;&#x5206;&#x6790;OBJC_TAG_Last60BitPayload&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x5230;&#x5C0F;&#x4E8E;&#x7B49;&#x4E8E;6&#x5305;&#x542B;&#x7684;&#x7C7B;&#x578B;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>    // 60-bit payloads
    OBJC_TAG_NSAtom            = 0, 
    OBJC_TAG_1                 = 1, 
    OBJC_TAG_NSString          = 2, 
    OBJC_TAG_NSNumber          = 3, 
    OBJC_TAG_NSIndexPath       = 4, 
    OBJC_TAG_NSManagedObjectID = 5, 
    OBJC_TAG_NSDate            = 6,
</code></pre>
<!--kg-card-end: markdown--><p>&#x70B9;&#x51FB;&#x65B9;&#x6CD5;&#x5185;&#x7684;&#x5B8F;&#x5B9A;&#x4E49;&#x8FDB;&#x53BB;&#xFF0C;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x4F4D;&#x79FB;&#x64CD;&#x4F5C;&#x6240;&#x5BF9;&#x5E94;&#x7684;&#x503C;&#xFF0C;&#x8FD9;&#x91CC;&#x53EA;&#x622A;&#x53D6;ARM64&#x6240;&#x5BF9;&#x5E94;&#x7684;</p><!--kg-card-begin: markdown--><pre><code>#if OBJC_SPLIT_TAGGED_POINTERS
#   define _OBJC_TAG_MASK (1UL&lt;&lt;63)
#   define _OBJC_TAG_INDEX_SHIFT 0
#   define _OBJC_TAG_SLOT_SHIFT 0
#   define _OBJC_TAG_PAYLOAD_LSHIFT 1
#   define _OBJC_TAG_PAYLOAD_RSHIFT 4
#   define _OBJC_TAG_EXT_MASK (_OBJC_TAG_MASK | 0x7UL)
#   define _OBJC_TAG_NO_OBFUSCATION_MASK ((1UL&lt;&lt;62) | _OBJC_TAG_EXT_MASK)
#   define _OBJC_TAG_CONSTANT_POINTER_MASK \
        ~(_OBJC_TAG_EXT_MASK | ((uintptr_t)_OBJC_TAG_EXT_SLOT_MASK &lt;&lt; _OBJC_TAG_EXT_SLOT_SHIFT))
#   define _OBJC_TAG_EXT_INDEX_SHIFT 55
#   define _OBJC_TAG_EXT_SLOT_SHIFT 55
#   define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 9
#   define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
</code></pre>
<!--kg-card-end: markdown--><p>&#x901A;&#x8FC7;&#x5206;&#x6790;&#x4EE3;&#x7801;&#x53EF;&#x5F97;&#xFF0C;&#x6307;&#x9488;&#x7684;&#x6700;&#x9AD8;1&#x4F4D;&#x662F;_OBJC_TAG_MASK&#xFF0C;&#x56E0;&#x4E3A;60&#x4F4D;payload&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;tag&#x7684;&#x6700;&#x5927;&#x503C;&#x662F;6&#xFF0C;&#x4E8C;&#x8FDB;&#x5236;&#x4F4D;110&#xFF0C;&#x53EF;&#x5F97;&#x6700;&#x4F4E;3&#x4F4D;&#x662F;tag&#xFF0C;&#x7136;&#x540E;&#x8FD4;&#x56DE;&#x7684;&#x503C;&#x8FD8;&#x8981;&#x901A;&#x8FC7;_objc_encodeTaggedPointer&#x5904;&#x7406;</p><!--kg-card-begin: markdown--><pre><code>static inline void * _Nonnull
_objc_encodeTaggedPointer(uintptr_t ptr)
{
    uintptr_t value = (objc_debug_taggedpointer_obfuscator ^ ptr);
#if OBJC_SPLIT_TAGGED_POINTERS
    if ((value &amp; _OBJC_TAG_NO_OBFUSCATION_MASK) == _OBJC_TAG_NO_OBFUSCATION_MASK)
        return (void *)ptr;
    uintptr_t basicTag = (value &gt;&gt; _OBJC_TAG_INDEX_SHIFT) &amp; _OBJC_TAG_INDEX_MASK;
    uintptr_t permutedTag = _objc_basicTagToObfuscatedTag(basicTag);
    value &amp;= ~(_OBJC_TAG_INDEX_MASK &lt;&lt; _OBJC_TAG_INDEX_SHIFT);
    value |= permutedTag &lt;&lt; _OBJC_TAG_INDEX_SHIFT;
#endif
    return (void *)value;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x5B9E;&#x9645;&#x7684;&#x503C;&#x8FD8;&#x9700;&#x8981;&#x5F02;&#x6216;&#x4E00;&#x4E2A;objc_debug_taggedpointer_obfuscator&#xFF0C;&#x641C;&#x7D22;&#x53EF;&#x7684;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x968F;&#x673A;&#x503C;&#xFF0C;&#x5E76;&#x4E14;&#x662F;&#x5728;iOS12&#x5F00;&#x59CB;&#x5F15;&#x5165;&#x7684;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>// tagged pointers are obfuscated by XORing with a random value
// decoded_obj = (obj ^ obfuscator)
OBJC_EXPORT uintptr_t objc_debug_taggedpointer_obfuscator
    OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
</code></pre>
<!--kg-card-end: markdown--><p>&#x7EE7;&#x7EED;&#x641C;&#x7D22;&#x627E;&#x5230;initializeTaggedPointerObfuscator(<strong>void</strong>)&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x5230;objc_debug_taggedpointer_obfuscator&#x786E;&#x5B9E;&#x662F;&#x4E2A;&#x968F;&#x673A;&#x503C;&#xFF0C;&#x5E76;&#x4E14;&#x81F3;&#x5C11;2018&#x540E;&#x7684;dyld&#x7248;&#x672C;&#x624D;&#x751F;&#x6548;</p><!--kg-card-begin: markdown--><pre><code>static void
initializeTaggedPointerObfuscator(void)
{
    if (!DisableTaggedPointerObfuscation &amp;&amp; dyld_program_sdk_at_least(dyld_fall_2018_os_versions)) {
        arc4random_buf(&amp;objc_debug_taggedpointer_obfuscator,
                       sizeof(objc_debug_taggedpointer_obfuscator));
        objc_debug_taggedpointer_obfuscator &amp;= ~_OBJC_TAG_MASK;
#if OBJC_SPLIT_TAGGED_POINTERS
        objc_debug_taggedpointer_obfuscator &amp;= ~(_OBJC_TAG_EXT_MASK | _OBJC_TAG_NO_OBFUSCATION_MASK);
        int max = 7;
        for (int i = max - 1; i &gt;= 0; i--) {
            int target = arc4random_uniform(i + 1);
            swap(objc_debug_tag60_permutations[i],
                 objc_debug_tag60_permutations[target]);
        }
#endif
    } else {
        objc_debug_taggedpointer_obfuscator = 0;
    }
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x518D;&#x641C;&#x7D22;DisableTaggedPointerObfuscation&#xFF0C;&#x53D1;&#x73B0;&#x8FD9;&#x662F;&#x4E2A;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#xFF0C;&#x662F;&#x53EF;&#x4EE5;&#x8BBE;&#x7F6E;&#x5173;&#x95ED;&#x6DF7;&#x6DC6;&#x7684;</p><!--kg-card-begin: markdown--><pre><code>OPTION( DisableTaggedPointerObfuscation, OBJC_DISABLE_TAG_OBFUSCATION,    &quot;disable obfuscation of tagged pointers&quot;)
</code></pre>
<!--kg-card-end: markdown--><p>&#x4E3A;&#x4E86;&#x65B9;&#x4FBF;&#x5206;&#x6790;&#xFF0C;&#x56DE;&#x5230;&#x5DE5;&#x7A0B;&#xFF0C;&#x628A;OBJC_DISABLE_TAG_OBFUSCATION&#x8BBE;&#x7F6E;&#x4E3A;YES</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/1655106278885.jpg" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1864" height="1006" srcset="https://lemonlie.com/content/images/size/w600/2022/06/1655106278885.jpg 600w, https://lemonlie.com/content/images/size/w1000/2022/06/1655106278885.jpg 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/1655106278885.jpg 1600w, https://lemonlie.com/content/images/2022/06/1655106278885.jpg 1864w" sizes="(min-width: 720px) 720px"></figure><p>&#x8FD0;&#x884C;&#x4F1A;&#x770B;&#x5230;&#x5982;&#x4E0B;&#x7ED3;&#x679C;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-15.48.05.png" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1506" height="388" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-13-at-15.48.05.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/Screen-Shot-2022-06-13-at-15.48.05.png 1000w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-15.48.05.png 1506w" sizes="(min-width: 720px) 720px"></figure><p>str2&#x5DF2;&#x7ECF;&#x4E0D;&#x518D;&#x662F;&#x6DF7;&#x6DC6;&#x7684;&#x72B6;&#x6001;&#xFF0C;&#x7136;&#x540E;&#x5728;&#x8C03;&#x8BD5;&#x7A97;&#x53E3;&#x8F93;&#x5165; p/t str2&#xFF0C;&#x67E5;&#x770B;&#x4E0B;&#x6307;&#x9488;&#x7684;2&#x8FDB;&#x5236;&#x7ED3;&#x679C;&#x5982;&#x4E0B;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-15.53.47.png" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1518" height="62" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-13-at-15.53.47.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/Screen-Shot-2022-06-13-at-15.53.47.png 1000w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-15.53.47.png 1518w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x6700;&#x9AD8;&#x4F4D;&#x4E3A;1&#xFF0C;&#x6700;&#x4F4E;3&#x4F4D;&#xFF0C;&#x5341;&#x8FDB;&#x5236;&#x4E3A;2&#xFF0C;OBJC_TAG_NSString=2&#xFF0C;&#x53EF;&#x4EE5;&#x8BC1;&#x660E;&#x5BF9;&#x51FD;&#x6570;&#x7684;&#x5206;&#x6790;&#x662F;&#x6B63;&#x786E;&#x7684;&#x3002;</p><p>&#x67E5;ASCII &#x8868;&#x53EF;&#x5F97;&#xFF0C;a&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#x4E3A;01100001&#xFF0C;&#x5206;&#x6790;&#x53EF;&#x5F97;&#x5982;&#x4E0B;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/1655107668889.jpg" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1512" height="124" srcset="https://lemonlie.com/content/images/size/w600/2022/06/1655107668889.jpg 600w, https://lemonlie.com/content/images/size/w1000/2022/06/1655107668889.jpg 1000w, https://lemonlie.com/content/images/2022/06/1655107668889.jpg 1512w" sizes="(min-width: 720px) 720px"></figure><p>TAG&#x548C;&#x503C;&#x4E2D;&#x95F4;4&#x4F4D;&#x8868;&#x793A;&#x4EC0;&#x4E48;&#x610F;&#x601D;&#x5462;&#xFF1F;&#x67E5;&#x8D44;&#x6599;&#x5F97;&#xFF0C;&#x8FD9;4&#x4F4D;&#x662F;Type Index&#xFF0C;&#x8868;&#x793A;&#x6570;&#x636E;&#x7684;&#x7C7B;&#x578B;&#x3002;&#x7136;&#x540E;&#x5199;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x5E2E;&#x52A9;&#x5206;&#x6790;&#xFF0C;&#x5E76;&#x5728;&#x6700;&#x540E;&#x4E00;&#x884C;&#x6253;&#x4E0A;&#x65AD;&#x70B9;</p><!--kg-card-begin: markdown--><pre><code>    NSNumber *number1 = [NSNumber numberWithChar:2];
    NSNumber *number2 = [NSNumber numberWithShort:2];
    NSNumber *number3 = [NSNumber numberWithInt:2];

    NSLog(@&quot;%@ %p %@&quot;,number1, number1, number1.class);
    NSLog(@&quot;%@ %p %@&quot;,number2, number2, number2.class);
    NSLog(@&quot;%@ %p %@&quot;,number3, number3, number3.class);
    NSLog(@&quot;END&quot;);
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD0;&#x884C;&#x540E;&#xFF0C;&#x5728;&#x8C03;&#x8BD5;&#x7A97;&#x53E3;&#xFF0C;&#x5206;&#x522B;&#x901A;&#x8FC7;p/t&#x8F93;&#x51FA;3&#x4E2A;&#x6307;&#x9488;&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#xFF0C;&#x53EF;&#x5F97;&#x5982;&#x4E0B;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-16.22.52.png" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1462" height="642" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-13-at-16.22.52.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/Screen-Shot-2022-06-13-at-16.22.52.png 1000w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-16.22.52.png 1462w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x4E0D;&#x540C;&#x7C7B;&#x578B;&#x503C;&#x786E;&#x5B9E;&#x662F;&#x4E0D;&#x4E00;&#x6837;&#x7684;&#xFF0C;char&#x4E3A;0&#x3001;short&#x4E3A;1&#xFF0C;int&#x4E3A;2&#x3002;&#x7136;&#x540E;&#x770B;&#x5230;&#x8FD9;&#x4E2A;&#x663E;&#x793A;&#x7684;&#x662F;<strong>__NSCFNumber&#x7C7B;&#x578B;&#xFF0C;</strong>&#x67E5;&#x770B;<a href="https://opensource.apple.com/tarballs/CF/?ref=lemonlie.com">CF&#x6E90;&#x7801;</a>&#xFF0C;&#x5728;CFNumber&#x91CC;&#x9762;&#x627E;&#x5230;&#x5982;&#x4E0B;&#x5B9A;&#x4E49;</p><!--kg-card-begin: markdown--><pre><code>static const struct {
    uint16_t canonicalType:5;	// canonical fixed-width type
    uint16_t floatBit:1;	// is float
    uint16_t storageBit:1;	// storage size (0: (float ? 4 : 8), 1: (float ? 8 : 16) bits)
    uint16_t lgByteSize:3;	// base-2 log byte size of public type
    uint16_t unused:6;
} __CFNumberTypeTable[] = {
    //&#x7701;&#x7565;
    /* kCFNumberCharType */	{kCFNumberSInt8Type, 0, 0, 0, 0},
    /* kCFNumberShortType */	{kCFNumberSInt16Type, 0, 0, 1, 0},
    /* kCFNumberIntType */	{kCFNumberSInt32Type, 0, 0, 2, 0},
    //&#x7701;&#x7565;
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x53D1;&#x73B0;Type Index&#x7684;&#x503C;&#x53EF;&#x4EE5;&#x548C;&#x8FD9;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x91CC;&#x9762;&#x7684;lgByteSize&#x5BF9;&#x5E94;&#x4E0A;&#x3002;</p><p>&#x7EFC;&#x4E0A;&#xFF0C;&#x53EF;&#x4EE5;&#x77E5;&#x9053;Tagged Pointer&#x5728;OBJC_TAG_Last60BitPayload&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x6700;&#x9AD8;1&#x4F4D;&#x662F;&#x6807;&#x5FD7;&#x4F4D;&#xFF0C;&#x56E0;&#x4E3A;define _OBJC_TAG_MASK (1UL&lt;&lt;63)&#xFF0C;&#x662F;1&#x7684;&#x8BDD;&#xFF0C;&#x5C31;&#x8868;&#x793A;&#x8FD9;&#x4E2A;&#x503C;&#x4E3A;Tagged Pointer&#x3002;</p><!--kg-card-begin: markdown--><pre><code>static inline bool 
_objc_isTaggedPointer(const void * _Nullable ptr)
{
    return ((uintptr_t)ptr &amp; _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x4F4E;3&#x4F4D;&#x8868;&#x793A;tag&#xFF0C;&#x533A;&#x5206;Tagged Pointer&#x7684;&#x7C7B;&#x578B;&#xFF0C;&#x4F4E;4-7&#x4F4D;&#x533A;&#x5206;&#x6570;&#x636E;&#x7C7B;&#x578B;&#x3002;&#x6240;&#x6709;&#x5269;&#x4E0B;&#x7684;56&#x4F4D;&#x53EF;&#x4EE5;&#x8868;&#x793A;&#x6570;&#x636E;&#x3002;&#x6700;&#x9AD8;&#x4F4D;&#x9884;&#x7559;&#x7B26;&#x53F7;&#x4F4D;&#xFF0C;&#x90A3;&#x4E48;&#x5269;&#x4E0B;55&#x4F4D;&#x53EF;&#x8868;&#x793A;&#x7406;&#x8BBA;&#x4E0A;&#x6700;&#x5927;&#x6570;&#x5B57;&#x8303;&#x56F4;&#x5C31;&#x662F;-2^55~2^55-1&#x8FD9;&#x4E48;&#x5927;&#xFF0C;&#x5341;&#x8FDB;&#x5236;&#x5C31;&#x662F;-36028797018963968&#xFF5E;36028797018963967&#x3002;&#x7136;&#x540E;&#x5199;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x6D4B;&#x8BD5;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>    NSNumber *number1 = [NSNumber numberWithLong:36028797018963967];
    NSNumber *number2 = [NSNumber numberWithLong:36028797018963968];
    NSNumber *number3 = [NSNumber numberWithLong:-36028797018963968];
    NSNumber *number4 = [NSNumber numberWithLong:-36028797018963967];

    NSLog(@&quot;%@ %p %@&quot;,number1, number1, number1.class);
    NSLog(@&quot;%@ %p %@&quot;,number2, number2, number2.class);
    NSLog(@&quot;%@ %p %@&quot;,number3, number3, number3.class);
    NSLog(@&quot;%@ %p %@&quot;,number4, number4, number4.class);
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8F93;&#x51FA;&#x7ED3;&#x679C;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-18.05.18.png" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1632" height="596" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-13-at-18.05.18.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/Screen-Shot-2022-06-13-at-18.05.18.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/Screen-Shot-2022-06-13-at-18.05.18.png 1600w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-18.05.18.png 1632w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x89C1;&#x6700;&#x5927;&#x503C;&#x786E;&#x5B9E;&#x662F;2^55-1&#xFF0C;&#x4F46;&#x662F;&#x6700;&#x5C0F;&#x503C;&#x5374;&#x662F;-2^55+1&#xFF0C;&#x4E3A;&#x4EC0;&#x4E48;&#x5462;&#xFF1F;&#x518D;&#x5199;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x6D4B;&#x8BD5;&#xFF0C;&#x65AD;&#x70B9;&#x6253;&#x5728;&#x6700;&#x540E;&#x4E00;&#x884C;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>    NSNumber *number1 = [NSNumber numberWithLong:-36028797018963968];
    NSNumber *number2 = [NSNumber numberWithLong:-36028797018963967];
    NSNumber *number3 = [NSNumber numberWithLong:-36028797018963966];

    NSLog(@&quot;%@ %p %@&quot;,number1, number1, number1.class);
    NSLog(@&quot;%@ %p %@&quot;,number2, number2, number2.class);
    NSLog(@&quot;%@ %p %@&quot;,number3, number3, number3.class);
    NSLog(@&quot;END&quot;);
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD0;&#x884C;&#x4EE3;&#x7801;&#xFF0C;&#x5728;&#x8C03;&#x8BD5;&#x7A97;&#x53E3;&#x5206;&#x522B;p/t&#x8F93;&#x51FA;number2&#x548C;number3&#x7684;&#x503C;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-18.18.04.png" class="kg-image" alt="Tagged Pointer &#x8BE6;&#x89E3;" loading="lazy" width="1698" height="578" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-13-at-18.18.04.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/Screen-Shot-2022-06-13-at-18.18.04.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/Screen-Shot-2022-06-13-at-18.18.04.png 1600w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-13-at-18.18.04.png 1698w" sizes="(min-width: 720px) 720px"></figure><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x6700;&#x5C0F;&#x503C;+1&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x503C;&#x4E3A;-36028797018963966&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x6570;&#x636E;&#x4F4D;&#x7684;&#x4EA7;&#x751F;&#x4E86;&#x8FDB;&#x4F4D;&#x3002;&#x5982;&#x679C;&#x6700;&#x5C0F;&#x503C;-1&#x7684;&#x8BDD;&#xFF0C;&#x5B58;&#x50A8;&#x6570;&#x503C;&#x7684;&#x6240;&#x6709;&#x4F4D;&#x90FD;&#x4E3A;0&#x4E86;,&#x8FD8;&#x9700;&#x8981;&#x591A;&#x4E00;&#x4F4D;&#x6765;&#x663E;&#x793A;&#x6570;&#x636E;&#x624D;&#x53EF;&#x4EE5;&#x3002;&#x6240;&#x4EE5;&#x6700;&#x5C0F;&#x503C;&#x4E3A;-2^55 + 1&#x3002;</p><p>&#x6240;&#x4EE5;Tagged Pointer&#x53EF;&#x8868;&#x793A;&#x7684;&#x6570;&#x5B57;&#x8303;&#x56F4;&#x662F;-2^55+1 ~ 2^55-1&#xFF0C;&#x8D85;&#x51FA;&#x8FD9;&#x4E2A;&#x8303;&#x56F4;&#x7684;&#x6570;&#x5B57;&#xFF0C;NSNumber&#x4F1A;&#x8F6C;&#x6362;&#x4E3A;&#x666E;&#x901A;&#x7684;Objective-C&#x5BF9;&#x8C61;&#x5206;&#x914D;&#x5728;&#x5806;&#x4E0A;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[Objective-C中self和super的区别]]></title><description><![CDATA[<p>self&#x548C;super&#x5728;&#x5F00;&#x53D1;&#x4E2D;&#x7ECF;&#x5E38;&#x9047;&#x5230;&#xFF0C;&#x6700;&#x5E38;&#x89C1;&#x7684;&#x573A;&#x666F;&#x5C31;&#x662F; self=[super init]&#xFF0C;&#x5F88;&#x660E;&#x663E;&#x8FD9;&#x662F;&#x4E24;&#x4E2A;&#x4E0D;&#x540C;&#x7684;&#x5173;&#x952E;&#x5B57;&#xFF0C;&#x80AF;&#x5B9A;&#x662F;&#x6709;&#x533A;&#x522B;&#x7684;&#x3002;</p><p>&#x5728;&#x5199;&#x533A;&#x522B;</p>]]></description><link>https://lemonlie.com/objective-c-zhong-self-he-super/</link><guid isPermaLink="false">65672ee96c00b44e3076578c</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Thu, 09 Jun 2022 11:49:33 GMT</pubDate><media:content url="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-09-at-19.59.22.png" medium="image"/><content:encoded><![CDATA[<img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-09-at-19.59.22.png" alt="Objective-C&#x4E2D;self&#x548C;super&#x7684;&#x533A;&#x522B;"><p>self&#x548C;super&#x5728;&#x5F00;&#x53D1;&#x4E2D;&#x7ECF;&#x5E38;&#x9047;&#x5230;&#xFF0C;&#x6700;&#x5E38;&#x89C1;&#x7684;&#x573A;&#x666F;&#x5C31;&#x662F; self=[super init]&#xFF0C;&#x5F88;&#x660E;&#x663E;&#x8FD9;&#x662F;&#x4E24;&#x4E2A;&#x4E0D;&#x540C;&#x7684;&#x5173;&#x952E;&#x5B57;&#xFF0C;&#x80AF;&#x5B9A;&#x662F;&#x6709;&#x533A;&#x522B;&#x7684;&#x3002;</p><p>&#x5728;&#x5199;&#x533A;&#x522B;&#x4E4B;&#x524D;&#xFF0C;&#x5148;&#x65B0;&#x5EFA;&#x4E2A;&#x5DE5;&#x7A0B;&#xFF0C;&#x7136;&#x540E;&#x521B;&#x5EFA;&#x4E2A;Ghost&#x7C7B;&#x6587;&#x4EF6;&#xFF0C;&#x5728;&#x6587;&#x4EF6;&#x4E2D;&#x5199;&#x5165;&#x4EE5;&#x4E0B;&#x65B9;&#x6CD5;&#x5E76;&#x8C03;&#x7528;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>- (void)run{
    NSLog(@&quot;%@&quot;, [self class]);
    NSLog(@&quot;%@&quot;, [super class]);
    
    NSLog(@&quot;%@&quot;, [self superclass]);
    NSLog(@&quot;%@&quot;, [super superclass]);
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x4F1A;&#x795E;&#x5947;&#x7684;&#x53D1;&#x73B0;&#xFF0C;self&#x548C;super&#x8C03;&#x7528;&#x76F8;&#x540C;&#x65B9;&#x6CD5;&#xFF0C;&#x8F93;&#x5165;&#x7684;&#x7ED3;&#x679C;&#x4E5F;&#x662F;&#x4E00;&#x6837;&#x7684;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-09-at-17.35.48.png" class="kg-image" alt="Objective-C&#x4E2D;self&#x548C;super&#x7684;&#x533A;&#x522B;" loading="lazy" width="926" height="412" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-09-at-17.35.48.png 600w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-09-at-17.35.48.png 926w" sizes="(min-width: 720px) 720px"></figure><p>&#x4E3A;&#x4EC0;&#x4E48;&#x5462;&#xFF1F;Objective-C&#x7684;&#x5E95;&#x5C42;&#x662F;C/C++&#x5C01;&#x88C5;&#x7684;&#xFF0C;&#x628A;&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x8F6C;&#x6210;C++&#x4EE3;&#x7801;&#x4EE5;&#x66F4;&#x597D;&#x7684;&#x5206;&#x6790;&#x3002;&#x8F6C;&#x4EE3;&#x7801;&#x4E4B;&#x524D;&#xFF0C;&#x5148;&#x628A;&#x4EE3;&#x7801;&#x7B80;&#x5316;&#x4E3A;&#x4EE5;&#x4E0B;&#xFF0C;&#x53EF;&#x4EE5;&#x66F4;&#x65B9;&#x9762;&#x67E5;&#x770B;&#x3002;</p><!--kg-card-begin: markdown--><pre><code>- (void)run{
    [self class];
    [super class];
    
    [self superclass];
    [super superclass];
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x6253;&#x5F00;&#x7EC8;&#x7AEF;&#xFF0C;&#x8FDB;&#x5165;&#x5230;Ghost.m&#x76EE;&#x5F55;&#xFF0C;&#x7136;&#x540E;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;</p><!--kg-card-begin: markdown--><pre><code>xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc Ghost.m -o Ghost.cpp
</code></pre>
<!--kg-card-end: markdown--><p>&#x7136;&#x540E;&#x6253;&#x5F00;Ghost.cpp&#x6587;&#x4EF6;&#xFF0C;&#x641C;&#x7D22;NSLog&#x5C31;&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>static void _I_Ghost_run(Ghost * self, SEL _cmd) {
    ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName(&quot;class&quot;));
    ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass(&quot;Ghost&quot;))}, sel_registerName(&quot;class&quot;));
    ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName(&quot;superclass&quot;));
    ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass(&quot;Ghost&quot;))}, sel_registerName(&quot;superclass&quot;));
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x7B80;&#x5316;&#x4EE3;&#x7801;&#xFF0C;&#x53EA;&#x7559;&#x4E0B;&#x4E86; self&#x548C;super&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x76F8;&#x5173;&#x5185;&#x5BB9;</p><!--kg-card-begin: markdown--><pre><code>objc_msgSend(self, sel_registerName(&quot;class&quot;));

objc_msgSendSuper((__rw_objc_super){self, class_getSuperclass(objc_getClass(&quot;Ghost&quot;))},
sel_registerName(&quot;class&quot;));

objc_msgSend(self, sel_registerName(&quot;superclass&quot;));

objc_msgSendSuper((__rw_objc_super){self, class_getSuperclass(objc_getClass(&quot;Ghost&quot;))}, sel_registerName(&quot;superclass&quot;));
</code></pre>
<!--kg-card-end: markdown--><p>&#x53D1;&#x73B0;self&#x7684;&#x8C03;&#x7528;&#x88AB;&#x8F6C;&#x6362;&#x6210;&#x4E86;objc_msgSend&#x8C03;&#x7528;&#xFF0C;&#x5C31;&#x662F;&#x5E38;&#x89C1;&#x7684;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x4E0D;&#x591A;&#x505A;&#x89E3;&#x91CA;&#x3002;</p><p>&#x800C;super&#x8C03;&#x7528;&#x7684;&#x5730;&#x65B9;&#xFF0C;&#x88AB;&#x8F6C;&#x6362;&#x6210;&#x4E86;objc_msgSendSuper&#x8C03;&#x7528;&#xFF0C;&#x5728;<a href="https://opensource.apple.com/tarballs/objc4/objc4-818.2.tar.gz?ref=lemonlie.com">objc4-818.2</a>&#x6E90;&#x7801;&#x4E2D;&#x641C;&#x7D22;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x5B9A;&#x4E49;&#x627E;&#x5230;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
</code></pre>
<!--kg-card-end: markdown--><p>struct objc_super&#x7684;&#x5B9A;&#x4E49;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>struct objc_super {
    /// Specifies an instance of a class.
    __unsafe_unretained _Nonnull id receiver;

    /// Specifies the particular superclass of the instance to message. 
    __unsafe_unretained _Nonnull Class super_class;
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#x7684;&#x7236;&#x7C7B;&#xFF0C;&#x56E0;&#x4E3A;Ghost&#x5BF9;&#x8C61;&#x7EE7;&#x627F;&#x4E8E;NSObject&#x90A3;&#x4E0A;&#x9762;&#x5173;&#x4E8E;super&#x8C03;&#x7528;&#x7684;&#x76F8;&#x5173;&#x4EE3;&#x7801; &#x5C31;&#x53EF;&#x4EE5;&#x7B80;&#x5316;&#x6210;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>objc_msgSendSuper({self, [NSObject class]}, @selector(class));
objc_msgSendSuper({self, [NSObject class]}, @selector(superclass));
</code></pre>
<!--kg-card-end: markdown--><p>objc_msgSendSuper&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#x505A;&#x4E86;&#x4EC0;&#x4E48;&#x5462;&#xFF1F;&#x6E90;&#x7801;&#x4E2D;&#x641C;&#x7D22;&#x4E0B;&#xFF0C;&#x627E;&#x5230;&#x5404;&#x4E2A;&#x5E73;&#x53F0;&#x7684;&#x6C47;&#x7F16;&#x4EE3;&#x7801;&#xFF0C;arm&#x5E73;&#x53F0;&#x76F8;&#x5173;&#x7684;&#x4EE3;&#x7801;&#x5982;&#x4E0B;(arm64&#x6C47;&#x7F16;&#x6BD4;&#x8FD9;&#x4E2A;&#x590D;&#x6742;&#xFF0C;&#x6574;&#x4F53;&#x903B;&#x8F91;&#x662F;&#x4E00;&#x6837;&#x7684;)</p><!--kg-card-begin: markdown--><pre><code>ENTRY _objc_msgSendSuper

ldr    r9, [r0, #CLASS]    // r9 = struct super-&gt;class
CacheLookup NORMAL, _objc_msgSendSuper
// cache hit, IMP in r12, eq already set for nonstret forwarding
ldr    r0, [r0, #RECEIVER]    // load real receiver
bx    r12            // call imp

CacheLookup2 NORMAL, _objc_msgSendSuper
// cache miss
ldr    r9, [r0, #CLASS]    // r9 = struct super-&gt;class
ldr    r0, [r0, #RECEIVER]    // load real receiver
b    __objc_msgSend_uncached

END_ENTRY _objc_msgSendSuper
</code></pre>
<!--kg-card-end: markdown--><p>&#x6C47;&#x7F16;&#x7684;&#x5927;&#x6982;&#x610F;&#x601D;&#x662F;&#xFF0C;r0(&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570; super)&#x4E2D;&#x53D6;&#x51FA;class(&#x8FD9;&#x91CC;&#x662F;NSObject) &#x5B58;&#x5165;r9, &#x7136;&#x540E;&#x4ECE;&#x8FD9;&#x4E2A;class&#x65B9;&#x6CD5;&#x7F13;&#x5B58;&#x4E2D;&#x627E;&#x65B9;&#x6CD5;&#x7684;&#x5B9E;&#x73B0;&#xFF0C;&#x5982;&#x679C;&#x627E;&#x5230;&#x5C31;&#x653E;&#x5165;r12&#x4E2D;&#xFF0C;&#x518D;&#x628A;receiver(&#x8FD9;&#x91CC;&#x662F;self)&#x653E;&#x5165;&#x5982;r0&#x4E2D;&#xFF0C;&#x7136;&#x540E;&#x518D;&#x8C03;&#x7528;&#x65B9;&#x6CD5;&#x3002;&#x518D;&#x4E0B;&#x9762;&#x662F;&#x5982;&#x679C;&#x5728;&#x65B9;&#x6CD5;&#x7F13;&#x5B58;&#x4E2D;&#x6CA1;&#x627E;&#x5230;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x7684;&#x8BDD;&#xFF0C;&#x628A;superclass&#x653E;&#x5165;r9&#xFF0C;&#x628A;receiver&#x653E;&#x5165;r0&#xFF0C;&#x7136;&#x540E;&#x8DF3;&#x8F6C;&#x5230;__objc_msgSend_uncached&#x65B9;&#x6CD5;&#xFF0C;&#x6C47;&#x7F16;&#x4EE3;&#x7801;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>STATIC_ENTRY __objc_msgSend_uncached

// THIS IS NOT A CALLABLE C FUNCTION
// Out-of-band r9 is the class to search

MethodTableLookup NORMAL    // returns IMP in r12
bx    r12

END_ENTRY __objc_msgSend_uncached
</code></pre>
<!--kg-card-end: markdown--><p>&#x610F;&#x601D;&#x662F;&#x4ECE;r9&#x4E2D;&#x641C;&#x7D22;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#xFF0C;MethodTableLookup &#x4F1A;&#x628A;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x653E;&#x5230;r12&#x5BC4;&#x5B58;&#x5176;&#x4E2D;&#xFF0C;bx r12&#x5C31;&#x662F;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x3002;</p><p>&#x4E0A;&#x9762;&#x903B;&#x8F91;&#x7B80;&#x5316;&#x5C31;&#x662F;&#xFF0C;&#x4ECE;r9&#x4E2D;(&#x4E5F;&#x5C31;&#x662F;&#x7236;&#x7C7B;)&#x641C;&#x7D22;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#xFF0C;&#x641C;&#x7D22;&#x5230;&#x653E;&#x5165;r12&#x4E2D;&#xFF0C;&#x7136;&#x540E;&#x8C03;&#x7528;&#x3002;&#x4E86;&#x89E3;arm&#x6C47;&#x7F16;&#x7684;&#x5C31;&#x4F1A;&#x77E5;&#x9053;&#xFF0C;&#x5728; Objective-C&#x4E2D;r0&#x5BC4;&#x5B58;&#x5668;&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#x5C31;&#x662F;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x8005;&#x3002;</p><p>&#x603B;&#x662F;&#xFF0C;self&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x4E00;&#x4E2A;&#x6307;&#x5411;&#x5F53;&#x524D;&#x8C03;&#x7528;&#x5BF9;&#x8C61;&#x7684;&#x6307;&#x9488;&#xFF0C;&#x5728;&#x8C03;&#x7528;&#x65B9;&#x6CD5;&#x65F6;&#x4F1A;&#x4F5C;&#x4E3A;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x4F20;&#x5165;objc_msgSend&#x65B9;&#x6CD5;&#x4E2D;&#x3002;super&#x662F;&#x4E00;&#x4E2A;&#x7F16;&#x8BD1;&#x5668;&#x6307;&#x793A;&#x7B26;&#xFF0C;&#x5728;&#x7F16;&#x8BD1;&#x7684;&#x65F6;&#x5019;&#x4F1A;&#x88AB;&#x66FF;&#x6362;&#x4E3A;</p><!--kg-card-begin: markdown--><pre><code>objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
</code></pre>
<!--kg-card-end: markdown--><p>&#x5E76;&#x4E14;&#x4F1A;&#x628A;&#x5F53;&#x524D;&#x8C03;&#x7528;&#x5BF9;&#x8C61;&#x548C;&#x5BF9;&#x8C61;&#x7684;&#x7236;&#x7C7B;&#x653E;&#x5165;&#x5230;objc_super&#x7ED3;&#x6784;&#x4F53;&#x4E2D;&#x4F5C;&#x4E3A;&#x65B9;&#x6CD5;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x3002;</p><p>&#x800C;objc_msgSendSuper&#x7684;&#x672C;&#x8D28;&#x5C31;&#x662F;&#xFF0C;&#x4ECE;&#x7236;&#x7C7B;&#x7684;&#x65B9;&#x6CD5;&#x5217;&#x8868;&#x4E2D;&#x67E5;&#x627E;&#x65B9;&#x6CD5;&#xFF0C;&#x8BA9;&#x5F53;&#x524D;&#x7C7B;&#x8C03;&#x7528;&#x3002;&#x56E0;&#x4E3A;class&#x548C;superclass&#x7684;&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x672C;&#x8EAB;&#x5C31;&#x5728;NSObject&#x4E2D;&#xFF0C;&#x7136;&#x540E;&#x8C03;&#x7528;&#x8005;&#x5176;&#x5B9E;&#x90FD;&#x662F;self&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x4E3A;&#x4EC0;&#x4E48;&#x8F93;&#x51FA;&#x7ED3;&#x679C;&#x90FD;&#x662F;&#x4E00;&#x6837;&#x7684;&#x539F;&#x56E0;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[搭建自己的云笔记-为知笔记私有部署]]></title><description><![CDATA[<p>&#x516C;&#x6709;&#x4E91;&#x7B14;&#x8BB0;&#x6709;&#x5F88;&#x591A;&#xFF0C;&#x5C31;&#x4E0D;&#x4E00;&#x4E00;&#x5217;&#x4E3E;&#x3002;&#x8FD9;&#x4E9B;&#x4E91;&#x7B14;&#x8BB0;&#x5404;&#x6709;&#x5404;&#x7684;&#x7279;&#x70B9;&#xFF0C;&#x4E0D;&#x8DB3;&#x7684;&#x662F;&#x6570;&#x636E;&#x4E0D;&#x53EF;&#x63A7;&#xFF0C;&#x5E76;&#x4E14;&#x90E8;&#x5206;&#x529F;&#x80FD;&#x9700;&#x8981;&#x4ED8;&#x8D39;&#x624D;&#x80FD;</p>]]></description><link>https://lemonlie.com/da-jian-zi-ji-de-yun-bi-ji/</link><guid isPermaLink="false">65672ee96c00b44e3076578b</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Wed, 08 Jun 2022 15:50:22 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1524591431555-cc7876d14adf?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDUzfHxub3RlfGVufDB8fHx8MTY1NDcwMzM0Ng&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1524591431555-cc7876d14adf?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDUzfHxub3RlfGVufDB8fHx8MTY1NDcwMzM0Ng&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="&#x642D;&#x5EFA;&#x81EA;&#x5DF1;&#x7684;&#x4E91;&#x7B14;&#x8BB0;-&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x79C1;&#x6709;&#x90E8;&#x7F72;"><p>&#x516C;&#x6709;&#x4E91;&#x7B14;&#x8BB0;&#x6709;&#x5F88;&#x591A;&#xFF0C;&#x5C31;&#x4E0D;&#x4E00;&#x4E00;&#x5217;&#x4E3E;&#x3002;&#x8FD9;&#x4E9B;&#x4E91;&#x7B14;&#x8BB0;&#x5404;&#x6709;&#x5404;&#x7684;&#x7279;&#x70B9;&#xFF0C;&#x4E0D;&#x8DB3;&#x7684;&#x662F;&#x6570;&#x636E;&#x4E0D;&#x53EF;&#x63A7;&#xFF0C;&#x5E76;&#x4E14;&#x90E8;&#x5206;&#x529F;&#x80FD;&#x9700;&#x8981;&#x4ED8;&#x8D39;&#x624D;&#x80FD;&#x4F7F;&#x7528;&#x3002;</p><p>&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x4E5F;&#x7B97;&#x662F;&#x8001;&#x724C;&#x7684;&#x7B14;&#x8BB0;&#x4E86;&#xFF0C;&#x4F46;&#x662F;&#x77E5;&#x9053;&#x7684;&#x4EBA;&#x5374;&#x4E0D;&#x662F;&#x5F88;&#x591A;&#x3002;&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x670D;&#x52A1;&#x7AEF;&#x63D0;&#x4F9B;&#x4E86;docker&#x955C;&#x50CF;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x7B80;&#x5355;&#x51E0;&#x6B65;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x5C06;&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x670D;&#x52A1;&#x7AEF;&#x90E8;&#x7F72;&#x5728;&#x81EA;&#x5DF1;&#x7684;&#x670D;&#x52A1;&#x5668;&#x4E0A;&#x3002;&#x9009;&#x62E9;&#x5B83;&#x7684;&#x539F;&#x56E0;&#x4E3B;&#x8981;&#x6709;&#x4EE5;&#x4E0B;&#x51E0;&#x70B9;&#x3002;</p><p>1&#x3001;&#x591A;&#x7AEF;&#x4E30;&#x5BCC;&#xFF0C;PC&#x3001;Mac&#x3001;iOS&#x3001;&#x5B89;&#x5353;&#x90FD;&#x6709;&#xFF0C;&#x4E14;&#x652F;&#x6301;&#x591A;&#x7AEF;&#x540C;&#x6B65;&#x3002;</p><p>2&#x3001;&#x6709;&#x52A0;&#x5BC6;&#x529F;&#x80FD;&#xFF0C;&#x6709;&#x4E9B;&#x4E2A;&#x4EBA;&#x8D44;&#x6599;&#x53EF;&#x4EE5;&#x52A0;&#x5BC6;&#x5904;&#x7406;&#x3002;</p><p>3&#x3001;&#x7B14;&#x8BB0;&#x652F;&#x6301;&#x591A;&#x7EA7;&#x76EE;&#x5F55;&#xFF0C;&#x5E76;&#x4E14;&#x652F;&#x6301;&#x591A;&#x683C;&#x5F0F;&#x5BFC;&#x51FA;&#x3002;</p><p>4&#x3001;&#x79C1;&#x6709;&#x7248;5 &#x7528;&#x6237;&#x4EE5;&#x4E0B;&#x514D;&#x8D39;&#x4F7F;&#x7528;&#x3002;</p><p>&#x6211;&#x7684;&#x670D;&#x52A1;&#x5668;&#x662F;&#x817E;&#x8BAF;&#x4E91;&#x7684;&#x4E91;&#x4E3B;&#x673A;&#xFF0C;&#x7CFB;&#x7EDF;&#x662F;Ubuntu Server 18.04.1 64&#x4F4D;&#x3002;&#x56E0;&#x4E3A;&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x662F;docker&#x955C;&#x50CF;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x88C5;&#x4E4B;&#x524D;&#x9700;&#x8981;&#x5148;&#x5B89;&#x88C5;docker&#x3002;&#x9996;&#x5148;&#x901A;&#x8FC7;&#x7EC8;&#x7AEF;&#x8FDE;&#x63A5;&#x5230;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x7136;&#x540E;&#x5728;&#x7EC8;&#x7AEF;&#x6309;&#x987A;&#x5E8F;&#x8F93;&#x5165;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x3002;</p><p>1&#x3001;&#x5148;&#x5378;&#x8F7D;&#x65E7;&#x7248;&#x672C;&#x7684;docker&#xFF1B;</p><pre><code>sudo apt-get remove docker docker-engine docker.io containerd runc
</code></pre>
<p>2&#x3001;&#x66F4;&#x65B0;apt&#x5305;&#x7D22;&#x5F15;&#xFF0C;&#x5E76;&#x5B89;&#x88C5;&#x4EE5;&#x4E0B;&#x5305;&#x4EE5;&#x5141;&#x8BB8;apt&#x901A;&#x8FC7; HTTPS &#x4F7F;&#x7528;&#x5B58;&#x50A8;&#x5E93;&#xFF1B;</p><pre><code>sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
</code></pre>
<p>3&#x3001;&#x6DFB;&#x52A0; Docker &#x7684;&#x5B98;&#x65B9; GPG &#x5BC6;&#x94A5;&#xFF1B;</p><pre><code>sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
</code></pre>
<p>4&#x3001;&#x8BBE;&#x7F6E;&#x5B58;&#x50A8;&#x5E93;&#xFF1B;</p><pre><code>echo &quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable&quot; | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null
</code></pre>
<p>5&#x3001;&#x66F4;&#x65B0;apt&#x5305;&#x7D22;&#x5F15;&#xFF0C;&#x5E76;&#x5B89;&#x88C5;docker&#xFF1B;</p><pre><code>sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
</code></pre>
<p>6&#x3001;&#x5B89;&#x88C5;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x6BCF;&#x6B21;&#x6267;&#x884C;&#x90FD;&#x9700;&#x8981;sudo&#x624D;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x6267;&#x884C;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x89E3;&#x51B3;</p><pre><code>sudo groupadd docker
sudo usermod -aG docker $USER
</code></pre>
<p>7&#x3001;&#x8BBE;&#x7F6E;&#x5F00;&#x673A;&#x542F;&#x52A8;&#xFF0C;&#x670D;&#x52A1;&#x5668;&#x91CD;&#x542F;&#x540E;docker&#x670D;&#x52A1;&#x53EF;&#x4EE5;&#x81EA;&#x542F;&#x52A8;&#x3002;</p><pre><code>sudo systemctl enable docker.service
sudo systemctl enable containerd.service
</code></pre>
<p>&#x73B0;&#x5728;&#x5728;&#x7EC8;&#x7AEF;&#x8F93;&#x5165; docker --version &#x80FD;&#x770B;&#x5230;docker&#x7684;&#x7248;&#x672C;&#x5C31;&#x8BC1;&#x660E;&#x5B89;&#x88C5;&#x6210;&#x529F;&#x4E86;&#x3002;&#x4EE5;&#x4E0A;&#x66F4;&#x8BE6;&#x7EC6;&#x5185;&#x5BB9;&#x53EF;&#x4EE5;&#x67E5;&#x770B;<a href="https://docs.docker.com/engine/install/ubuntu/?ref=lemonlie.com">&#x5B98;&#x65B9;&#x8BF4;&#x660E;&#x6587;&#x6863;</a>&#x3002;</p><p>docker&#x5B89;&#x88C5;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x73B0;&#x5728;&#x5C31;&#x53EF;&#x4EE5;&#x90E8;&#x7F72;&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x4E86;&#x3002;&#x5728;&#x7EC8;&#x7AEF;&#x8F93;&#x5165;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;</p><pre><code>cd ~
mkdir wizdata
</code></pre>
<p>&#x8FD9;&#x4E2A;&#x662F;&#x8FDB;&#x5165;&#x5F53;&#x524D;&#x7528;&#x6237;&#x76EE;&#x5F55;&#xFF0C;&#x521B;&#x5EFA;wizdata&#x76EE;&#x5F55;&#xFF0C;&#x4E5F;&#x662F;&#x53EF;&#x4EE5;&#x521B;&#x5EFA;&#x5176;&#x4ED6;&#x4F4D;&#x7F6E;&#x7684;&#xFF0C;&#x4E0D;&#x8FC7;&#x540E;&#x7EED;&#x547D;&#x4EE4;&#x9700;&#x8981;&#x5BF9;&#x5E94;&#x4FEE;&#x6539;&#xFF0C;&#x65B0;&#x624B;&#x4E0D;&#x5EFA;&#x8BAE;&#x66F4;&#x6539;&#x76EE;&#x5F55;&#x3002;</p><pre><code>docker run --name wiz --restart=always -it -d -v  ~/wizdata:/wiz/storage -v  /etc/localtime:/etc/localtime -p 8080:80 -p 9269:9269/udp  wiznote/wizserver

</code></pre>
<p>&#x5982;&#x679C;wizdata&#x4E0D;&#x5728;&#x7528;&#x6237;&#x6839;&#x76EE;&#x5F55;&#xFF0C;&#x9700;&#x8981;&#x628A;~/wizdata&#x6539;&#x5230;&#x5BF9;&#x5E94;&#x7684;&#x8DEF;&#x5F84;&#x3002;&#x7B49;&#x547D;&#x4EE4;&#x6267;&#x884C;&#x5B8C;&#x6210;&#xFF0C;&#x6CA1;&#x62A5;&#x9519;&#x7684;&#x8BDD;&#x79C1;&#x6709;&#x7B14;&#x8BB0;&#x5C31;&#x90E8;&#x7F72;&#x5B8C;&#x6210;&#x4E86;&#x3002;</p><p>&#x6253;&#x5F00;&#x6D4F;&#x89C8;&#x5668;&#xFF0C;&#x5728;&#x5730;&#x5740;&#x680F;&#x8F93;&#x5165; <strong><em>&#x670D;&#x52A1;&#x5668;&#x7684;IP&#x5730;&#x5740;:8080</em></strong>&#xFF0C;&#x6572;&#x56DE;&#x8F66;&#x3002;&#x5C31;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x5982;&#x4E0B;&#x754C;&#x9762;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/be0563b0-da94-11e9-b6e3-2953c693f8f7.png" class="kg-image" alt="&#x642D;&#x5EFA;&#x81EA;&#x5DF1;&#x7684;&#x4E91;&#x7B14;&#x8BB0;-&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x79C1;&#x6709;&#x90E8;&#x7F72;" loading="lazy" width="2000" height="1182" srcset="https://lemonlie.com/content/images/size/w600/2022/06/be0563b0-da94-11e9-b6e3-2953c693f8f7.png 600w, https://lemonlie.com/content/images/size/w1000/2022/06/be0563b0-da94-11e9-b6e3-2953c693f8f7.png 1000w, https://lemonlie.com/content/images/size/w1600/2022/06/be0563b0-da94-11e9-b6e3-2953c693f8f7.png 1600w, https://lemonlie.com/content/images/size/w2400/2022/06/be0563b0-da94-11e9-b6e3-2953c693f8f7.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>&#x9ED8;&#x8BA4;&#x7BA1;&#x7406;&#x5458;&#x8D26;&#x53F7;&#xFF1A;admin@wiz.cn&#xFF0C;&#x5BC6;&#x7801;&#xFF1A;123456&#x3002;&#x8BF7;&#x5728;&#x90E8;&#x7F72;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x4F7F;&#x7528;&#x8FD9;&#x4E2A;&#x8D26;&#x53F7;&#xFF0C;&#x767B;&#x5F55;&#x7F51;&#x9875;&#x7248;&#xFF0C;&#x7136;&#x540E;&#x4FEE;&#x6539;&#x7BA1;&#x7406;&#x5458;&#x5BC6;&#x7801;&#x3002;</p><p>&#x4EE5;&#x4E0A;&#x66F4;&#x591A;&#x5185;&#x5BB9;&#x53EF;&#x4EE5;&#x67E5;&#x770B;<a href="https://www.wiz.cn/zh-cn/docker.html?ref=lemonlie.com">&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x5B98;&#x65B9;&#x6587;&#x6863;</a>&#x3002;</p><p>&#x867D;&#x7136;&#x90E8;&#x7F72;&#x5B8C;&#x6210;&#x4E86;&#xFF0C;&#x4F46;&#x662F;&#x53C8;&#x6709;&#x4E9B;&#x95EE;&#x9898;&#x9700;&#x8981;&#x8003;&#x8651;&#x4E0B;&#x3002;&#x4E00;&#x76F4;&#x4F7F;&#x7528;IP&#x52A0;&#x7AEF;&#x53E3;&#x8BBF;&#x95EE;&#x7684;&#x65B9;&#x5F0F;&#x4E0D;&#x591F;&#x7F8E;&#x89C2;&#xFF0C;&#x5E76;&#x4E14;&#x5982;&#x679C;&#x670D;&#x52A1;&#x5668;&#x6362;IP&#x6216;&#x8005;&#x7AEF;&#x53E3;&#x6362;&#x4E86;&#xFF0C;&#x5BA2;&#x6237;&#x7AEF;&#x90FD;&#x9700;&#x8981;&#x66F4;&#x6539;&#xFF0C;&#x7528;&#x57DF;&#x540D;&#x8BBF;&#x95EE;&#x624D;&#x662F;&#x66F4;&#x597D;&#x7684;&#x89E3;&#x51B3;&#x529E;&#x6CD5;&#x3002;&#x6CE8;&#x518C;&#x57DF;&#x540D;&#x548C;&#x57DF;&#x540D;&#x89E3;&#x6790;&#x5728;&#x8FD9;&#x91CC;&#x4E0D;&#x5C31;&#x8BF4;&#x4E86;&#x3002;</p><p>&#x8FD9;&#x91CC;&#x4E3B;&#x8981;&#x8BF4;&#x4E0B;nginx&#x7684;&#x5B89;&#x88C5;&#x4E86;&#x914D;&#x7F6E;&#x3002;&#x5B89;&#x88C5;&#x6BD4;&#x8F83;&#x7B80;&#x5355;&#xFF0C;&#x8F93;&#x5165;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x5373;&#x53EF;</p><pre><code>sudo apt-get install nginx
</code></pre>
<p>&#x5B89;&#x88C5;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x8F93;&#x5165;&#x670D;&#x52A1;&#x5668;&#x7684;IP&#x5730;&#x5740;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x770B;&#x5230;nginx&#x7684;&#x8BF4;&#x660E;&#x754C;&#x9762;&#x3002;&#x5982;&#x679C;&#x770B;&#x4E0D;&#x5230;&#x53EF;&#x80FD;&#x8FD8;&#x9700;&#x8981;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#xFF0C;&#x6253;&#x5F00;nginx&#x5BF9;&#x5E94;&#x7684;&#x7AEF;&#x53E3;&#x5E76;&#x4E14;&#x542F;&#x52A8;nginx&#x3002;</p><pre><code>sudo ufw allow &apos;Nginx Full&apos;
sudo systemctl restart nginx
</code></pre>
<p>&#x7136;&#x540E;&#x5C31;&#x662F;&#x7533;&#x8BF7;&#x514D;&#x8D39;&#x7684;HTTPS&#x8BC1;&#x4E66;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;acme.h&#x7533;&#x8BF7;&#xFF0C;&#x8BE6;&#x7EC6;&#x5185;&#x5BB9;&#x770B;<a href="https://github.com/acmesh-official/acme.sh/wiki?ref=lemonlie.com">&#x8FD9;&#x91CC;</a>&#x3002;</p><p>&#x8BC1;&#x4E66;&#x7533;&#x8BF7;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x8FDB;&#x5165;nginx&#x76EE;&#x5F55;&#x521B;&#x5EFA;&#x57DF;&#x540D;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF0C;&#x914D;&#x7F6E;nginx&#x53CD;&#x5411;&#x4EE3;&#x7406;&#x3002;</p><pre><code>cd /etc/nginx/sites-available/
</code></pre>
<p>&#x901A;&#x8FC7;&#x4E0A;&#x9762;&#x547D;&#x4EE4;&#x8FDB;&#x5165;&#x7684;nginx&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x76EE;&#x5F55;&#xFF0C;&#x7136;&#x540E;</p><pre><code>vi &#x57DF;&#x540D;.conf //&#x57DF;&#x540D;&#x66FF;&#x6362;&#x4E3A;&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x5BF9;&#x5E94;&#x7684;&#x57DF;&#x540D;&#xFF0C;&#x7528;&#x4E8E;&#x533A;&#x5206;
</code></pre>
<p>&#x7136;&#x540E;&#x6309; i &#x8FDB;&#x5165;&#x7F16;&#x8F91;&#x6A21;&#x5F0F;&#xFF0C;&#x590D;&#x5236;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#xFF0C;&#x628A;&#x4E2D;&#x6587;&#x66FF;&#x6362;&#x4E3A;&#x76F8;&#x5E94;&#x57DF;&#x540D;&#xFF0C;&#x518D;&#x7C98;&#x8D34;&#x8FDB;&#x53BB;&#x5373;&#x53EF;&#x3002;</p><pre><code>server {
    listen 80;
    server_name &#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x57DF;&#x540D;;
    return	301 https://&#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x57DF;&#x540D;$request_uri;
}

server{
    listen 443 ssl;
    server_name &#x4E3A;&#x77E5;&#x7B14;&#x8BB0;&#x57DF;&#x540D;;
    ssl on;

    ssl_certificate 	/etc/nginx/ssl/&#x8BC1;&#x4E66;&#x76EE;&#x5F55;/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/&#x8BC1;&#x4E66;&#x76EE;&#x5F55;/key.pem;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;

    access_log   /var/log/nginx/wzi.log;
    error_log    /var/log/nginx/wzi_error.log;

    root /var/www/blog/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &quot;upgrade&quot;;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header x-wiz-real-ip $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8080;
    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

</code></pre>
<p>&#x7136;&#x540E; &#x6309;ESC&#x9000;&#x51FA;&#x7F16;&#x8F91;&#x6A21;&#x5F0F;&#xFF0C;&#x5728;&#x7EC8;&#x7AEF;&#x952E;&#x5165;:wq! &#x56DE;&#x8F66;&#x4FDD;&#x5B58;&#x5E76;&#x9000;&#x51FA;&#x7F16;&#x8F91;&#x5668;&#x3002;<a href="https://www.wiz.cn/zh-cn/docker-https.html?ref=lemonlie.com">&#x5B98;&#x65B9;&#x914D;&#x7F6E;&#x770B;&#x8FD9;&#x91CC;</a></p><p>&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x5176;&#x5B9E;&#x8FD8;&#x5E76;&#x6CA1;&#x6709;&#x751F;&#x6548;&#x3002;&#x53EA;&#x6709;&#x5728;sites-enabled&#x76EE;&#x5F55;&#x4E0B;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x624D;&#x662F;&#x542F;&#x7528;&#x7684;&#x914D;&#x7F6E;&#x3002;&#x73B0;&#x5728;&#x5C31;&#x9700;&#x8981;&#x8FDB;&#x5165;&#x521B;&#x5EFA;&#x4E2A;&#x8F6F;&#x94FE;&#x63A5;&#x6307;&#x5411;&#x521A;&#x521B;&#x5EFA;&#x7684;&#x6587;&#x4EF6;&#x5373;&#x53EF;&#xFF0C;&#x7136;&#x540E;&#x91CD;&#x542F;nginx&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x62A5;&#x9519;&#xFF0C;&#x5230;&#x8FD9;&#x91CC;&#x79C1;&#x6709;&#x7B14;&#x8BB0;&#x5C31;&#x90E8;&#x7F72;&#x6210;&#x529F;&#x4E86;&#x3002;</p><pre><code>sudo ln -s /etc/nginx/sites-available/&#x57DF;&#x540D;.conf /etc/nginx/sites-enabled/&#x57DF;&#x540D;.conf

sudo systemctl restart nginx 
</code></pre>
]]></content:encoded></item><item><title><![CDATA[深入理解isa指针]]></title><description><![CDATA[<p>&#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#x7684;isa&#x6307;&#x9488;&#x6307;&#x5BF9;&#x8C61;&#x7684;&#x7C7B;&#xFF0C;&#x7C7B;&#x5BF9;&#x8C61;&#x7684;isa&#x6307;&#x9488;&#x6307;&#x5411;&#x5BF9;&#x8C61;&#x7684;&#x5143;&#x7C7B;&#xFF0C;&#x8FD9;&#x79CD;&#x8BF4;&#x6CD5;&#x5BF9;&#x5417;&#xFF1F;</p><p>&#x5BF9;&#xFF0C;&#x4F46;&#x4E5F;&#x4E0D;&#x5B8C;&#x5168;&#x5BF9;&#x3002;&#x56E0;&#x4E3A;&#x5728;arm64&#x67B6;</p>]]></description><link>https://lemonlie.com/shen-ru-li-jie-isa/</link><guid isPermaLink="false">65672ee96c00b44e3076578a</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Wed, 08 Jun 2022 10:05:06 GMT</pubDate><media:content url="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-08-at-18.04.28.png" medium="image"/><content:encoded><![CDATA[<img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-08-at-18.04.28.png" alt="&#x6DF1;&#x5165;&#x7406;&#x89E3;isa&#x6307;&#x9488;"><p>&#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#x7684;isa&#x6307;&#x9488;&#x6307;&#x5BF9;&#x8C61;&#x7684;&#x7C7B;&#xFF0C;&#x7C7B;&#x5BF9;&#x8C61;&#x7684;isa&#x6307;&#x9488;&#x6307;&#x5411;&#x5BF9;&#x8C61;&#x7684;&#x5143;&#x7C7B;&#xFF0C;&#x8FD9;&#x79CD;&#x8BF4;&#x6CD5;&#x5BF9;&#x5417;&#xFF1F;</p><p>&#x5BF9;&#xFF0C;&#x4F46;&#x4E5F;&#x4E0D;&#x5B8C;&#x5168;&#x5BF9;&#x3002;&#x56E0;&#x4E3A;&#x5728;arm64&#x67B6;&#x6784;&#x4E4B;&#x524D;&#xFF0C;isa&#x786E;&#x5B9E;&#x53EA;&#x5B58;&#x50A8;&#x7740;Class&#x3001;Meta-Class&#x5BF9;&#x8C61;&#x7684;&#x5185;&#x5B58;&#x5730;&#x5740;&#xFF0C;&#x4F46;&#x662F;&#x5728;&#x4E4B;&#x540E;&#x82F9;&#x679C;&#x5BF9;isa&#x8FDB;&#x884C;&#x4E86;&#x4F18;&#x5316;&#xFF0C;&#x53D8;&#x6210;&#x4E86;&#x4E00;&#x4E2A;&#x5171;&#x7528;&#x4F53;&#x7ED3;&#x6784;&#xFF0C;&#x4F7F;&#x5176;&#x80FD;&#x7528;&#x4F4D;&#x57DF;&#x5B58;&#x50A8;&#x66F4;&#x591A;&#x7684;&#x4FE1;&#x606F;&#x3002;&#x800C;&#x6307;&#x5411;Class&#x7684;&#x6307;&#x9488;&#x9700;&#x8981;&#x6309;&#x4F4D;&#x4E0E;&#x4E2A;ISA_MASK&#x624D;&#x53EF;&#x4EE5;&#x83B7;&#x53D6;&#x5230;&#x3002;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/image.webp" class="kg-image" alt="&#x6DF1;&#x5165;&#x7406;&#x89E3;isa&#x6307;&#x9488;" loading="lazy" width="550" height="575"></figure><p>&#x4E0A;&#x56FE;&#x662F;&#x4E00;&#x5F20;&#x5F88;&#x7ECF;&#x5178;&#x7684;&#x6307;&#x9488;&#x6307;&#x5411;&#x56FE;&#xFF0C;&#x867D;&#x7136;&#x5DF2;&#x7ECF;&#x4E0D;&#x5B8C;&#x5168;&#x6B63;&#x786E;&#xFF0C;&#x4F46;&#x662F;&#x8FD8;&#x662F;&#x53EF;&#x4EE5;&#x4F5C;&#x4E3A;&#x53C2;&#x8003;&#x7684;&#x3002;</p><p>&#x4E0A;&#x4E00;&#x7BC7;&#x6587;&#x7AE0;&#x63D0;&#x5230;&#xFF0C;isa&#x6307;&#x9488;&#x88AB;&#x4F18;&#x5316;&#x6210;union isa_t&#x7C7B;&#x578B;&#xFF0C;&#x6E90;&#x7801;&#x4E2D;&#x641C;&#x7D22;&#x53EF;&#x4EE5;&#x5728;objc-private.h&#x6587;&#x4EF6;&#x4E2D;&#x627E;&#x5230;&#x5B9A;&#x4E49;&#xFF0C;&#x53BB;&#x9664;&#x65B9;&#x6CD5;&#x7B80;&#x5316;&#x540E;&#x7684;&#x4EE3;&#x7801;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>union isa_t {
    uintptr_t bits;
private:
    Class cls;
public:
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x7136;&#x540E;&#x518D;isa.h&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x627E;&#x5230;ISA_BITFIELD&#x7684;&#x5B9A;&#x4E49;&#xFF0C;&#x5FFD;&#x7565;x86&#x548C;&#x6A21;&#x62DF;&#x5668;&#xFF0C;&#x628A;&#x5B9A;&#x4E49;&#x66FF;&#x6362;&#x5230;&#x4EE5;&#x4E0A;&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;&#x53EF;&#x4EE5;&#x53D8;&#x6210;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>union isa_t {
    uintptr_t bits;
private:
    Class cls;
public:
    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 unused            : 1;
        uintptr_t has_sidetable_rc  : 1; 
        uintptr_t extra_rc          : 19
    };
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x90A3;&#x8FD9;&#x4E9B;&#x7ED3;&#x6784;&#x4F53;&#x91CC;&#x9762;&#x7684;&#x4E1C;&#x897F;&#x90FD;&#x8868;&#x793A;&#x4EC0;&#x4E48;&#x610F;&#x601D;&#x5462;&#xFF1F;&#x53EF;&#x4EE5;&#x5728;&#x6E90;&#x7801;&#x91CC;&#x9762;&#x641C;&#x7D22;&#x627E;&#x4E0B;&#x7B54;&#x6848;&#xFF0C;&#x6211;&#x7684;&#x6E90;&#x7801;&#x7248;&#x672C;&#x662F;objc4-818.2&#xFF0C;&#x4E0D;&#x540C;&#x7248;&#x672C;&#x53EF;&#x80FD;&#x4E0D;&#x592A;&#x4E00;&#x6837;&#x3002;</p><p>&#x641C;&#x7D22;<strong>isa.nonpointer; </strong>&#x4F1A;&#x627E;&#x5230;&#x4E00;&#x4E2A; hasNonpointerIsa()&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#x4F7F;&#x7528;&#x4E86;&#xFF0C;&#x7136;&#x540E;&#x7EE7;&#x7EED;&#x641C;&#x7D22;hasNonpointerIsa()&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x5728;objc-object.h&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x6709;&#x4E24;&#x4E2A;&#x5730;&#x65B9;&#x5B9A;&#x4E49;&#x4E86;&#x8FD9;&#x4E2A;&#x51FD;&#x6570;&#xFF0C;&#x4E3A;&#x4EC0;&#x4E48;&#x4F1A;&#x6709;&#x4E24;&#x4E2A;&#x5462;&#xFF0C;&#x4E0D;&#x4F1A;&#x51B2;&#x7A81;&#x5417;&#xFF1F;&#x6240;&#x4EE5;&#x4E00;&#x5B9A;&#x6709;&#x6761;&#x4EF6;&#x7F16;&#x8BD1;&#x6307;&#x4EE4;&#x533A;&#x5206;&#x7F16;&#x8BD1;&#x3002;&#x7EE7;&#x7EED;&#x67E5;&#x627E;&#x4EE3;&#x7801;&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;(&#x7B80;&#x5316;&#x4EE3;&#x7801;)</p><!--kg-card-begin: markdown--><pre><code>#if SUPPORT_NONPOINTER_ISA  //line 172
inline bool 
objc_object::hasNonpointerIsa()
{
    return isa.nonpointer;
}
#else //line 952
inline bool 
objc_object::hasNonpointerIsa()
{
    return false;
}
#endif //1217
</code></pre>
<!--kg-card-end: markdown--><p>&#x5BF9;&#x6BD4;&#x4E0B;&#x5F88;&#x660E;&#x663E;&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x5728;SUPPORT_NONPOINTER_ISA&#x90E8;&#x5206;&#xFF0C;&#x8FD4;&#x56DE;&#x503C;&#x5E94;&#x8BE5;&#x4E3A;true&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x5F53;nonpointer&#x4E3A;1&#x65F6;&#xFF0C;&#x8868;&#x793A;&#x4F18;&#x5316;&#x8FC7;&#x7684;&#x6307;&#x9488;&#x3002;</p><p>&#x641C;&#x7D22;<strong>isa.has_assoc; </strong>&#x627E;&#x5230;&#x4E2A;hasAssociatedObjects()&#x65B9;&#x6CD5;&#x88AB;&#x8C03;&#x7528;&#xFF0C;&#x7136;&#x540E;&#x641C;&#x7D22;<strong>has_assoc =</strong> &#x627E;&#x5230;setHasAssociatedObjects()&#x65B9;&#x6CD5;&#x4E2D;&#x88AB;&#x8BBE;&#x7F6E;&#x4E3A;true&#xFF0C;&#x4F46;&#x662F;&#x5E76;&#x6CA1;&#x6709;&#x8BBE;&#x7F6E;&#x4E3A;false&#x7684;&#x5730;&#x65B9;&#x3002;&#x6240;&#x4EE5;&#x5F53;&#x8FD9;&#x4E2A;&#x503C;&#x4E3A;1&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x8868;&#x793A;&#x88AB;&#x8BBE;&#x7F6E;&#x8FC7;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x3002;</p><p>&#x641C;&#x7D22;isa.has_cxx_dtor; &#x627E;&#x5230;hasCxxDtor()&#xFF0C;&#x7136;&#x540E;&#x641C;&#x7D22;hasCxxDtor()&#x65B9;&#x6CD5;&#x5728;objc-private.h&#x6587;&#x4EF6;&#x4E2D;&#x627E;&#x5230;&#x4EE5;&#x4E0B;&#x6CE8;&#x91CA;</p><!--kg-card-begin: markdown--><pre><code>// object may have -.cxx_destruct implementation?
bool hasCxxDtor();
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x8FD9;&#x4E2A;&#x503C;&#x8868;&#x793A;&#x5BF9;&#x8C61;&#x662F;&#x5426;&#x6709;C++&#x7684;&#x6790;&#x6784;&#x51FD;&#x6570;&#x3002;&#x82F9;&#x679C;&#x6807;&#x8BC6;&#x8FD9;&#x4E9B;&#x7684;&#x4F5C;&#x7528;&#x662F;&#x4EC0;&#x4E48;&#x5462;&#xFF1F;</p><p>&#x641C;&#x7D22;hasCxxDtor();&#x65B9;&#x6CD5;&#xFF0C;&#x53D1;&#x73B0;objc-runtime-new.mm&#x6587;&#x4EF6;&#x4E2D;&#x5982;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>void *objc_destructInstance(id obj) 
{
    if (obj) {
        // Read all of the flags at once for performance.
        bool cxx = obj-&gt;hasCxxDtor();
        bool assoc = obj-&gt;hasAssociatedObjects();

        // This order is important.
        if (cxx) object_cxxDestruct(obj);
        if (assoc) _object_remove_assocations(obj, /*deallocating*/true);
        obj-&gt;clearDeallocating();
    }

    return obj;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x5728;&#x5BF9;&#x8C61;&#x91CA;&#x653E;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x7528;&#x4E8E;&#x5224;&#x65AD;&#x662F;&#x5426;&#x6709;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x548C;C++&#x7684;&#x6790;&#x6784;&#x51FD;&#x6570;&#xFF0C;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x7684;&#x8BDD;&#xFF0C;&#x53EF;&#x4EE5;&#x66F4;&#x5FEB;&#x7684;&#x91CA;&#x653E;&#x5BF9;&#x8C61;&#x3002;</p><p>&#x641C;&#x7D22;shiftcls&#xFF0C;&#x5E76;&#x6CA1;&#x6709;&#x627E;&#x5230;&#x6709;&#x7528;&#x7684;&#x4FE1;&#x606F;&#x3002;&#x4E0D;&#x8FC7;&#x770B;&#x540D;&#x5B57;&#x731C;&#x6D4B;&#x4E00;&#x5B9A;&#x548C;&#x7C7B;&#x6709;&#x5173;&#x7CFB;&#xFF0C;&#x5982;&#x679C;&#x83B7;&#x53D6;&#x7C7B;&#x6307;&#x9488;&#x7684;&#x8BDD;&#xFF0C;&#x9700;&#x8981;&#x5728;&#x73B0;&#x6709;&#x7684;isa&#x6307;&#x9488;&#x4E0A;&#x6309;&#x4F4D;&#x4E0E;ISA_MASK&#xFF0C;&#x67E5;&#x770B;&#x4E0B;ISA_MASK&#x7684;&#x503C;&#x4E3A;0x0000000ffffffff8ULL&#xFF0C;&#x590D;&#x5236;&#x7C98;&#x8D34;&#x5230;&#x8BA1;&#x7B97;&#x5668;&#x5982;&#x56FE;</p><figure class="kg-card kg-image-card"><img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-08-at-17.22.20.png" class="kg-image" alt="&#x6DF1;&#x5165;&#x7406;&#x89E3;isa&#x6307;&#x9488;" loading="lazy" width="802" height="394" srcset="https://lemonlie.com/content/images/size/w600/2022/06/Screen-Shot-2022-06-08-at-17.22.20.png 600w, https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-08-at-17.22.20.png 802w" sizes="(min-width: 720px) 720px"></figure><p>&#x770B;&#x5230;&#x503C;&#x4E3A;1&#x7684;&#x4F4D;&#x7684;&#x957F;&#x5EA6;&#x6B63;&#x597D;&#x548C;shiftcls&#x7684;&#x957F;&#x5EA6;&#x5BF9;&#x5E94;&#x4E0A;&#xFF0C;&#x6309;&#x7167;&#x6309;&#x4F4D;&#x4E0E;&#x7684;&#x903B;&#x8F91;&#xFF0C;&#x4FDD;&#x7559;&#x503C;&#x4E3A;1&#x5BF9;&#x5E94;&#x90E8;&#x5206;&#x7684;&#x503C;&#x3002;&#x53EF;&#x4EE5;&#x786E;&#x5B9A;shiftcls &#x5B58;&#x50A8;&#x7684;Class&#x3001;Meta-Class&#x5BF9;&#x8C61;&#x7684;&#x5185;&#x5B58;&#x5730;&#x5740;&#x4FE1;&#x606F;&#x3002;</p><p>&#x6E90;&#x7801;&#x4E2D;&#x641C;&#x7D22;magic&#xFF0C;&#x5E76;&#x6CA1;&#x6709;&#x627E;&#x5230;&#x592A;&#x591A;&#x6709;&#x7528;&#x7684;&#x4FE1;&#x606F;&#xFF0C;&#x901A;&#x8FC7;&#x67E5;&#x8BE2;&#x8D44;&#x6599;&#xFF0C;&#x5F97;&#x77E5;&#x8FD9;&#x4E2A;&#x503C;&#x662F;&#x4E3A;&#x4E86;&#x5728;&#x8C03;&#x8BD5;&#x7684;&#x65F6;&#x5019;&#x5206;&#x8FA8;&#x5BF9;&#x8C61;&#x662F;&#x5426;&#x672A;&#x5B8C;&#x6210;&#x521D;&#x59CB;&#x5316;&#x3002;</p><p>weakly_referenced &#x4ECE;&#x5B57;&#x9762;&#x610F;&#x601D;&#x5C31;&#x80FD;&#x770B;&#x51FA;&#xFF0C;&#x8FD9;&#x4E2A;&#x6807;&#x8BC6;&#x662F;&#x5426;&#x6709;&#x5F31;&#x5F15;&#x7528;&#x3002;&#x76F8;&#x540C;&#x65B9;&#x6CD5;&#x641C;&#x7D22;&#x5F97;&#x5982;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>// object may be weakly referenced?
bool isWeaklyReferenced();
</code></pre>
<!--kg-card-end: markdown--><p>&#x641C;&#x7D22;extra_rc; &#x4F1A;&#x627E;&#x5230;&#x5982;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>inline uintptr_t 
objc_object::rootRetainCount()
{
    if (isTaggedPointer()) return (uintptr_t)this;

    sidetable_lock();
    isa_t bits = __c11_atomic_load((_Atomic uintptr_t *)&amp;isa.bits, __ATOMIC_RELAXED);
    if (bits.nonpointer) {
        uintptr_t rc = bits.extra_rc;
        if (bits.has_sidetable_rc) {
            rc += sidetable_getExtraRC_nolock();
        }
        sidetable_unlock();
        return rc;
    }

    sidetable_unlock();
    return sidetable_retainCount();
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;extra_rc&#x5B58;&#x50A8;&#x503C;&#x4E3A;&#x5BF9;&#x8C61;&#x7684;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#xFF0C;&#x540C;&#x65F6;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x5F53;has_sidetable_rc&#x4E3A;1&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x8FD8;&#x9700;&#x8981;&#x52A0;&#x4E0A;&#x53E6;&#x4E00;&#x4E2A;&#x503C;&#x624D;&#x80FD;&#x5F97;&#x5230;&#x51C6;&#x786E;&#x7684;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#x3002;</p><p>&#x4EC0;&#x4E48;&#x65F6;&#x5019;&#x624D;&#x4F1A;&#x628A;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#x5199;&#x5230;sidetable&#x4E2D;&#x5462;&#x3002;&#x641C;&#x7D22;has_sidetable_rc = true &#x5F97;&#x5230;&#x5982;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>    if (slowpath(carry)) {
        // newisa.extra_rc++ overflowed
        if (variant != RRVariant::Full) {
            ClearExclusive(&amp;isa.bits);
            return rootRetain_overflow(tryRetain);
        }
        // Leave half of the retain counts inline and
        // prepare to copy the other half to the side table.
        if (!tryRetain &amp;&amp; !sideTableLocked) sidetable_lock();
        sideTableLocked = true;
        transcribeToSideTable = true;
        newisa.extra_rc = RC_HALF;
        newisa.has_sidetable_rc = true;
    }

</code></pre>
<!--kg-card-end: markdown--><p>&#x53D1;&#x73B0;newisa.extra_rc++ overflowed&#xFF0C;&#x5F53;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#x8FC7;&#x5927;&#x65E0;&#x6CD5;&#x5B58;&#x5165;&#x5230;extra_rc&#xFF0C;&#x4F1A;&#x628A;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#x5199;&#x5165;&#x5230;sidetable&#x91CC;&#x9762;&#xFF0C;&#x5E76;&#x628A;has_sidetable_rc&#x8BBE;&#x7F6E;&#x4E3A;true&#xFF0C;extra_rc&#x7684;&#x503C;&#x8BBE;&#x7F6E;&#x4E3A;RC_HALF&#xFF0C;&#x67E5;&#x770B;&#x5B8F;&#x5B9A;&#x4E49;&#x7684;&#x503C;define RC_HALF &#xA0;(1ULL&lt;&lt;18)&#xFF0C;&#x53EF;&#x5F97;extra_rc&#x6700;&#x5927;&#x5B58;&#x50A8;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#x4E3A;2^18 - 1 = 262143&#x3002;</p><p>&#x901A;&#x8FC7;&#x4EE5;&#x4E0A;&#x5185;&#x5BB9;&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x4F18;&#x5316;&#x540E;&#x7684;&#x6307;&#x9488;&#x53EF;&#x4EE5;&#x5B58;&#x50A8;&#x5F88;&#x591A;&#x5185;&#x5BB9;&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x66F4;&#x6709;&#x6548;&#x7387;&#x7684;&#x83B7;&#x53D6;&#x5B58;&#x50A8;&#x7684;&#x5185;&#x5BB9;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[Objective-C 对象的本质是什么]]></title><description><![CDATA[<p>&#x4F5C;&#x4E3A;&#x4E00;&#x4E2A;iOS&#x5F00;&#x53D1;&#xFF0C;&#x63A5;&#x89E6;&#x6700;&#x591A;&#x7684;&#x53EF;&#x80FD;&#x5C31;&#x662F;Objective-C&#x8BED;&#x8A00;&#x4E86;&#xFF0C;&#x4F17;&#x6240;&#x5468;&#x77E5;Objective-C&#x662F;&#x4E00;&#x79CD;&#x9762;&#x5411;&#x5BF9;&#x8C61;&#x7684;&#x8BED;&#x8A00;&#xFF0C;&#x82F9;&#x679C;&#x7528;C/C++&#x4E3A;&#x5176;&#x5C01;&#x88C5;&#x4E86;&#x6210;&#x5458;</p>]]></description><link>https://lemonlie.com/objective-c-dui-xiang-de-ben-zhi-shi-shen-me/</link><guid isPermaLink="false">65672ee96c00b44e30765789</guid><dc:creator><![CDATA[LEMON]]></dc:creator><pubDate>Thu, 02 Jun 2022 07:02:33 GMT</pubDate><media:content url="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-07-at-20.20.27.png" medium="image"/><content:encoded><![CDATA[<img src="https://lemonlie.com/content/images/2022/06/Screen-Shot-2022-06-07-at-20.20.27.png" alt="Objective-C &#x5BF9;&#x8C61;&#x7684;&#x672C;&#x8D28;&#x662F;&#x4EC0;&#x4E48;"><p>&#x4F5C;&#x4E3A;&#x4E00;&#x4E2A;iOS&#x5F00;&#x53D1;&#xFF0C;&#x63A5;&#x89E6;&#x6700;&#x591A;&#x7684;&#x53EF;&#x80FD;&#x5C31;&#x662F;Objective-C&#x8BED;&#x8A00;&#x4E86;&#xFF0C;&#x4F17;&#x6240;&#x5468;&#x77E5;Objective-C&#x662F;&#x4E00;&#x79CD;&#x9762;&#x5411;&#x5BF9;&#x8C61;&#x7684;&#x8BED;&#x8A00;&#xFF0C;&#x82F9;&#x679C;&#x7528;C/C++&#x4E3A;&#x5176;&#x5C01;&#x88C5;&#x4E86;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x3001;&#x65B9;&#x6CD5;&#x7684;&#x5B58;&#x50A8;&#x548C;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x903B;&#x8F91;&#xFF0C;&#x4F46;&#x662F;&#x5177;&#x4F53;&#x7684;&#x5B9E;&#x73B0;&#x5E76;&#x6CA1;&#x6709;&#x66B4;&#x9732;&#x7ED9;&#x6211;&#x4EEC;&#x3002;</p><p>&#x5206;&#x6790;&#x4E4B;&#x524D;&#xFF0C;&#x9700;&#x8981;&#x5148;&#x65B0;&#x5EFA;&#x4E2A;Command Line Tool&#x5DE5;&#x7A0B;&#xFF0C;&#x7136;&#x540E;&#x518D;main&#x6587;&#x4EF6;&#x4E2D;&#x5199;&#x5165;&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#xFF1A;</p><!--kg-card-begin: markdown--><pre><code>@interface Ghost : NSObject
{
    int age;
}
@end

@implementation Ghost
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Ghost *ghost = [[Ghost alloc] init];
    }
    return 0;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x7136;&#x540E;&#x9700;&#x8981;&#x628A;&#x5B83;&#x8F6C;&#x6210;C/C++&#x4EE3;&#x7801;&#xFF0C;&#x6253;&#x5F00;&#x7EC8;&#x7AEF;&#xFF0C;&#x8FDB;&#x5165;main&#x6587;&#x4EF6;&#x6240;&#x5728;&#x7684;&#x76EE;&#x5F55;&#xFF0C;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;</p><!--kg-card-begin: markdown--><pre><code>xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main_arm64.cpp
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x4E2A;&#x547D;&#x4EE4;&#x7684;&#x610F;&#x601D;&#x662F;&#xFF0C;&#x628A;main.m&#x6587;&#x4EF6;&#x4E2D;&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x8F6C;&#x6362;&#x6210;iOS&#x5E73;&#x53F0;&#x5BF9;&#x5E94;&#x7684;C++&#x4EE3;&#x7801;&#x3002;&#x63A5;&#x4E0B;&#x6765;&#x6253;&#x5F00;main_arm64.cpp&#x6587;&#x4EF6;&#xFF0C;&#x641C;&#x7D22;&#x7C7B;&#x540D; Ghost&#xFF0C;&#x4F1A;&#x627E;&#x5230;Ghost_IMPL&#x7684;&#x7ED3;&#x6784;&#x4F53;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>typedef struct objc_object Ghost;
struct Ghost_IMPL {
	struct NSObject_IMPL NSObject_IVARS;
        int age;
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x4ECE;&#x8FD9;&#x91CC;&#x4E0D;&#x96BE;&#x53D1;&#x73B0;Objective-C&#x5BF9;&#x8C61;&#x7684;&#x672C;&#x8D28;&#x5C31;&#x662F;<strong>objc_object</strong>&#x7C7B;&#x578B;&#x7684;&#x7ED3;&#x6784;&#x4F53;&#x3002;&#x7ED3;&#x6784;&#x4F53;&#x91CC;&#x9762;&#x6709;&#x4E00;&#x4E2A;NSObject_IMPL&#x7C7B;&#x578B;&#x7684;&#x7ED3;&#x6784;&#x4F53;&#x548C;&#x4E00;&#x4E2A;int&#x7C7B;&#x578B;&#x540D;&#x5B57;&#x4E3A;age&#x7684;&#x53D8;&#x91CF;&#xFF0C;&#x8FD9;&#x4E2A;NSObject_IMPL&#x53C8;&#x662F;&#x4EC0;&#x4E48;&#x5462;&#xFF1F;&#x53EF;&#x4EE5;&#x5728;main_arm64.cpp&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x641C;&#x7D22;NSObject_IMPL&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x4E00;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x5982;&#x4E0B;</p><!--kg-card-begin: markdown--><pre><code>typedef struct objc_object NSObject;
struct NSObject_IMPL {
	Class isa;
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x4E0D;&#x96BE;&#x731C;&#x51FA;&#xFF0C;&#x8FD9;&#x4E2A;&#x5E94;&#x8BE5;&#x662F;NSobject&#x7C7B;&#x7684;&#x5E95;&#x5C42;&#x5B9E;&#x73B0;&#xFF0C;&#x901A;&#x8FC7;Xcode&#x8FDB;&#x5165;NSObject&#x7684;&#x5934;&#x6587;&#x4EF6;&#xFF0C;&#x4F1A;&#x53D1;&#x73B0;&#x7C7B;&#x7684;&#x5B9E;&#x73B0;&#x662F;&#x8FD9;&#x6837;&#x7684;</p><!--kg-card-begin: markdown--><pre><code>@interface NSObject &lt;NSObject&gt; {
    Class isa  OBJC_ISA_AVAILABILITY;
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x4E0A;&#x4E0B;&#x5BF9;&#x6BD4;&#x4E0B;&#xFF0C;&#x53EF;&#x4EE5;&#x8BC1;&#x660E;&#x731C;&#x6D4B;&#x662F;&#x6B63;&#x786E;&#x7684;&#x3002;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x770B;&#x5230;NSObject&#x5BF9;&#x8C61;&#x91CC;&#x9762;&#x53EA;&#x6709;&#x4E00;&#x4E2A; Class &#x7C7B;&#x578B;&#x7684;isa&#x6307;&#x9488;&#x3002;</p><p>&#x8FD9;&#x4E2A;Class&#x7C7B;&#x578B;&#x53C8;&#x662F;&#x4EC0;&#x4E48;&#x5462;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;Xcode&#x8FDB;&#x5165;objc.h&#x627E;&#x5230;&#x5982;&#x4E0B;&#x4EE3;&#x7801;</p><!--kg-card-begin: markdown--><pre><code>typedef struct objc_class *Class;

struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

typedef struct objc_object *id;
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FD9;&#x91CC;&#x80FD;&#x770B;&#x5230;Class&#x662F;struct objc_class&#x7C7B;&#x578B;&#x7684;&#x6307;&#x9488;&#xFF0C;&#x540C;&#x65F6;&#x53EF;&#x4EE5;&#x770B;&#x5230;id&#x662F;struct objc_object&#x7C7B;&#x578B;&#x7684;&#x6307;&#x9488;&#x3002;</p><p>&#x90A3;&#x4E48;struct objc_class&#x5185;&#x90E8;&#x53C8;&#x662F;&#x4EC0;&#x4E48;&#x6837;&#x5B50;&#x7684;&#x7ED3;&#x6784;&#x5462;&#xFF0C;Xcode&#x5E76;&#x4E0D;&#x80FD;&#x8DF3;&#x5230;&#x5B9A;&#x4E49;&#x7684;&#x5730;&#x65B9;&#xFF0C;&#x8FD9;&#x65F6;&#x5019;&#x5C31;&#x9700;&#x8981;&#x67E5;&#x770B;&#x82F9;&#x679C;&#x5F00;&#x6E90;&#x7684;&#x4EE3;&#x7801;&#x4E86;&#x3002;</p><p>&#x4ECE;&#x8FD9;&#x91CC;&#x4E0B;&#x8F7D;<a href="https://opensource.apple.com/tarballs/objc4/?ref=lemonlie.com">&#x6700;&#x65B0;&#x6E90;&#x7801;</a>&#xFF0C;&#x7248;&#x672C;&#x53F7;&#x6700;&#x5927;&#x7684;&#x5C31;&#x662F;&#x82F9;&#x679C;&#x5F00;&#x6E90;&#x7684;&#x6700;&#x65B0;&#x7684;&#x4EE3;&#x7801;&#x3002;&#x4E0B;&#x8F7D;&#x5B8C;&#x6210;&#x540E;&#x89E3;&#x538B;,&#x6211;&#x4E0B;&#x8F7D;&#x7684;&#xFF08;objc4-818.2&#xFF09;&#xFF0C;&#x7528;Xcode&#x6253;&#x5F00;&#x5DE5;&#x7A0B;&#x3002;&#x8FD9;&#x65F6;&#x5019;&#x641C;&#x7D22;struct objc_class&#xFF0C;&#x53D1;&#x73B0;&#x6709;&#x4E24;&#x4E2A;&#x6587;&#x4EF6;&#x5B9A;&#x4E49;&#x4E86;&#x8FD9;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#xFF08;objc-runtime-new.h&#x548C;objc-runtime-old.h&#xFF09;&#xFF0C;&#x5FFD;&#x7565;old&#x76F4;&#x63A5;&#x770B;new,&#x53EF;&#x4EE5;&#x627E;&#x5230;&#x5982;&#x4E0B;&#x5B9A;&#x4E49;&#xFF08;line 1688&#xFF09;</p><!--kg-card-begin: markdown--><pre><code>struct objc_class : objc_object {
    //&#x7701;&#x7565;...
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;   
    //&#x7701;&#x7565;...
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53EF;&#x4EE5;&#x770B;&#x5230;objc_class&#x662F;&#x7EE7;&#x627F;&#x4E8E;objc_object&#x7684;&#x7ED3;&#x6784;&#x4F53;&#xFF0C;&#x7136;&#x540E;&#x518D;&#x641C;&#x7D22;&#x4E0B;struct objc_object&#xFF0C;&#x4F1A;&#x5728;objc-private.h&#x627E;&#x5230;&#x5982;&#x4E0B;&#x5B9A;&#x4E49;</p><!--kg-card-begin: markdown--><pre><code>struct objc_object {
private:
    isa_t isa;
//&#x7701;&#x7565; ...
}
</code></pre>
<!--kg-card-end: markdown--><p>&#x53D1;&#x73B0;isa&#x6307;&#x9488;&#x5E76;&#x4E0D;&#x662F;Class&#x7C7B;&#x578B;&#x7684;&#x4E86;&#xFF0C;&#x90A3;&#x662F;&#x56E0;&#x4E3A;&#x82F9;&#x679C;&#x5728;64&#x4F4D;&#x7CFB;&#x7EDF;&#xFF0C;&#x4E3A;&#x4E86;&#x8BA9;&#x6307;&#x9488;&#x5B58;&#x50A8;&#x66F4;&#x591A;&#x7684;&#x6570;&#x636E;&#xFF0C;isa&#x6307;&#x9488;&#x4F18;&#x5316;&#x6210;union isa_t&#x7684;&#x7C7B;&#x578B;&#xFF0C;&#x627E;&#x5230;isa_t&#x7684;&#x5B9A;&#x4E49;</p><!--kg-card-begin: markdown--><pre><code>union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }
    uintptr_t bits;

private:
    Class cls;
    void setClass(Class cls, objc_object *obj);
    Class getClass(bool authenticated);
    Class getDecodedClass(bool authenticated);
};
</code></pre>
<!--kg-card-end: markdown--><p>&#x8FDB;&#x5165;getClass&#x65B9;&#x6CD5;&#x91CC;&#x9762;&#xFF0C;&#x4F1A;&#x53D1;&#x73B0; clsbits &amp;= ISA_MASK&#xFF0C;&#x53EF;&#x4EE5;&#x5F97;&#x77E5;&#x73B0;&#x5728;&#x6307;&#x5411;Class&#x7684;&#x6307;&#x9488;&#x9700;&#x8981;&#x518D;&#x6309;&#x4F4D;&#x4E0E;ISA_MASK&#x540E;&#x624D;&#x53EF;&#x4EE5;&#x5F97;&#x5230;&#x3002;</p><p>&#x7EFC;&#x4E0A;&#xFF0C;Objective-C &#x4E2D;</p><p>1&#x3001;&#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#x662F;<strong>objc_object</strong>&#x7C7B;&#x578B;&#x7684;&#x7ED3;&#x6784;&#x4F53;&#xFF0C;&#x91CC;&#x9762;&#x5305;&#x542B;isa&#x6307;&#x9488;&#x548C;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x3002;</p><p>2&#x3001;&#x7C7B;&#x5BF9;&#x8C61;&#x662F;<strong>objc_class</strong>&#x7C7B;&#x578B;&#x7684;&#x7ED3;&#x6784;&#x4F53;&#xFF0C;&#x56E0;&#x4E3A;&#x7EE7;&#x627F;&#x4E8E;<strong>objc_object</strong>&#x7C7B;&#x578B;&#xFF0C;&#x6240;&#x4EE5;&#x540C;&#x6837;&#x5305;&#x542B;isa&#x6307;&#x9488;&#xFF0C;&#x8FD8;&#x6709;superclass&#x6307;&#x9488;&#x7B49;&#x7C7B;&#x7684;&#x4E00;&#x4E9B;&#x4FE1;&#x606F;&#x3002;</p><p>3&#x3001;&#x5143;&#x7C7B;&#x4E5F;&#x662F;Class&#x7C7B;&#x578B;&#xFF0C;&#x540C;&#x6837;&#x4E5F;&#x662F;<strong>objc_class</strong>&#x7C7B;&#x578B;&#x7684;&#x7ED3;&#x6784;&#x4F53;&#x3002;</p>]]></content:encoded></item></channel></rss>