• [objc explain]: Non-fragile ivars


    [objc explain]: Non-fragile ivars   (2009-01-27 09:30 PM)
     

    Non-fragile instance variables are a headline feature of the modern Objective-C runtime available on iPhone and 64-bit Mac. They provide framework developers more flexibility without losing binary compatibility, and pave the way for automatically-synthesized property ivars and ivars declared outside a class's interface.

    The fragile base class problem

    Fragile ivars are a subset of the classic fragile base class problem. In some languages, a superclass cannot be changed without also recompiling all subclasses of that class. For example, adding data members or virtual member functions to a C++ superclass will break binary compatibility with any subclass of that class, even if the added members are private and invisible to the subclass. 

    In classic Objective-C, methods are mostly non-fragile, thanks to dynamic message dispatch. You can freely add methods to a superclass, as long as you don't have name conflicts. But Objective-C ivars are fragile on 32-bit Mac.

    32-bit Mac: fragile Objective-C ivars

    Say you're writing the world's next great pet shop application for Mac OS X Leopard. You might have this PetShopView subclass of NSView, with arrays for the puppies and kittens in the pet shop.

    NSView (Leopard)
    0 Class isa
    4 NSRect bounds
    20 NSView *superview
    24 NSColor *bgColor
    PetShopView
    0 Class isa
    4 NSRect bounds
    20 NSView *superview
    24 NSColor *bgColor
    28 NSArray *kittens
    32 NSArray *puppies

    Then Mac OS X Def Leopard comes out, with its new multi-paw interface technology. The AppKit developers add some paw-tracking code to NSView.

    NSView (Def Leopard)
    0 Class isa
    4 NSRect bounds
    20 NSView *superview
    24 NSColor *bgColor
    28 NSSet *touchedPaws
    PetShopView
    0 Class isa
    4 NSRect bounds
    20 NSView *superview
    24 NSColor *bgColor
    28 NSArray *kittens
    32 NSArray *puppies

    Unfortunately, your kittens are doomed by fragile ivars. Alternatively, the AppKit developers are trapped with whatever ivars they chose in Mac OS X 10.0.

    iPhone and 64-bit Mac: non-fragile Objective-C ivars

    What you and the AppKit developers really want is something like this.

    NSView (Def Leopard)
    0 Class isa
    4 NSRect bounds
    20 NSView *superview
    24 NSColor *bgColor
    28 NSSet *touchedPaws
    PetShopView
    0 Class isa
    4 NSRect bounds
    20 NSView *superview
    24 NSColor *bgColor
    28 NSSet *touchedPaws
    32 NSArray *kittens
    36 NSArray *puppies

    Here, the runtime has recognized that NSView is now larger than it was when PetShopView was compiled. The subclass ivars slide in response, without recompiling any code, and the kittens are saved by a dynamic runtime.

    How it works

    The generated code for classic Objective-C ivar access works like a C struct field. The offset to the ivar is a constant determined at compile time. The new ivar code instead creates a variable for each ivar which contains the offset to that ivar, and all code that accesses the ivar uses that variable. At launch time, the runtime can change any ivar offset variable if it detects an oversize superclass. 

    In the pet shop example, _OBJC_IVAR_PetShopView_kittens is 28 at compile time, but the runtime changes it to 32 when it sees the Def Leopard version of NSView. No code needs to be recompiled, and the performance overhead of the extra ivar offset variable is small. AppKit is happy, you're happy, and the kittens are happy.

    http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html

    解决了二进制的兼容性问题。没有 non-fragile ivars 特性,SuperClass 增删了成员变量,SubClass 必须重新编译才能正常运行。原因是 fragile ivars 环境下,成员变量在对象内存中的偏移量是编译阶段确定的,作为常量 hardcode 到指令中(这一点不确定,求证之后回来 update )。如果 SuperClass 增删了成员变量,那么 SubClass 的成员变量在内存中的偏移量就会变成错误的,因为 SubClass 的成员变量是排布在 SuperClass 的成员变量之后的,SuperClass 的成员变量的增删会导致 SubClass 成员变量的后移、迁移,使用原来的 offset 将无法取到正确的成员变量。
    ————————————————
    版权声明:本文为CSDN博主「海洋顶端」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/fly1183989782/article/details/81050782

  • 相关阅读:
    【InfoPath2007】The form has been closed
    深入浅出Nintex——调用子流程
    深入浅出Nintex——使用查询XML动作
    深入浅出Nintex——使用Call WebService来查询Item ID
    深入浅出Nintex——获得某群组的用户集合
    深入浅出SharePoint2007——Webpart开发
    深入浅出Nintex——获得指定用户的角色
    深入浅出Nintex——使用构建动态字符串动作
    Lucene.net 实现全文搜索
    DotLucene源码浅读笔记(1)补遗:编写简单中文分词器ChineseAnalyzer
  • 原文地址:https://www.cnblogs.com/feng9exe/p/10276195.html
Copyright © 2020-2023  润新知