关联引用是如何实现的?

2023-12-07

我在这里看到了一个非常好的示例:子类 UIButton 添加属性

它是什么?您无法将对象添加到类别。但现在有了这个技巧你就可以了。

那么它是什么?它是如何工作的?

Objective-c 对象已经有一些恒定数量的 ivar 指针,对吗?

现在你再加一个吗?他们是怎么想出来的?

我必须承认这是一个相当丑陋的符号。


使用关联引用技巧,您实际上并没有添加任何实例数据到 UIButton 对象。相反,您使用完全独立的 Cocoa 工具来创建新的字典映射(或联想) 现有的 UIButton 对象以及存储在堆中其他位置的数据。

您可以在不使用 Cocoa 的关联引用的情况下做完全相同的事情;它只会变得更加丑陋并且可能效率更低。在 Objective-C++ 中,它会是这样的。 (我什至不打算尝试用 Objective-C 编写它,因为CFMutableDictionary and NSMutableDictionary两者在几个层面上都有错误的行为,我不会从头开始写整个事情。然而,C++ 的std::map不能与__weak引用了我想要使用它的方式,所以我依靠这种低效的方式std::vector算法。对于那些不熟悉 C++ 的人:std::vector大致相当于NSMutableArray,但您可以选择是否保留其内容。)

重点是 UIButton 对象没有被改变;改变的是这个附加字典的内容。属性 getter 和 setter 只是知道如何在字典中查找内容,以便它appears就像 UIButton 有一个新属性一样。

#import "UIButton+Property.h"
#import <algorithm>
#import <vector>

typedef std::pair<__weak id, __strong id> EntryType;
static std::vector<EntryType> myAR;

@implementation UIButton(Property)

-(void) setProperty:(id)property
{
    for (int i=0; i < myAR.size(); ++i) {
        if (myAR[i].first == self) {
            myAR[i].second = property;
            return;
        }
    }
    myAR.push_back(EntryType(self, property));
}

-(id) property
{
    /* To save space, periodically erase the dictionary entries for
     * UIButton objects that have been deallocated. You can skip this
     * part, and even use NSMutableDictionary instead of this C++
     * stuff, if you don't care about leaking memory all over the place.
     */
    size_t n = myAR.size();
    for (size_t i=0; i < n; ++i) {
        if (myAR[i].first == nil)
            myAR[i] = myAR[--n];
    }
    myAR.resize(n);

    /* Look up "self" in our dictionary. */
    for (size_t i=0; i < myAR.size(); ++i) {
        EntryType &entry = myAR[i];
        if (entry.first == self) {
            return entry.second;
        }
    }
    return nil;
}

@end

也可以看看:http://labs.vectorform.com/2011/07/objective-c-linked-objects/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关联引用是如何实现的? 的相关文章

随机推荐

  • 有没有办法在 Lightswitch 中基于下拉菜单创建搜索屏幕

    我想在搜索屏幕上的搜索框所在位置放置一个下拉列表 并将每个条目与不同的查询相关联 这是针对我的业务中使用的数据库 我们目前有太多屏幕 例如 所有设备 新设备 可用设备 出售设备 未付费设备 未付佣金 我正在使用 2012 RC 的 Ligh
  • 字符串重复被连字符替换C++

    我是编码的初学者 正在尝试这个问题 用连字符替换字符串中字母的所有重复 即 ABCDAKEA 将变为 ABCD KE 我使用了 switch 循环并且它有效 但我想让它更短 也许使用递归来使其更有效 有任何想法吗 include
  • iOS 绘制两端弯曲的矩形

    想象一个长矩形 尺寸可能为 200x20 所有侧面都有直边 在我的 iOS 应用程序中 这对我来说很容易绘制 CGContextFillRect context CGRectMake xLoc yLoc 200 20 现在 如果我希望较短的
  • 如何使用 Android 从 NFC 标签检测制造商?

    我正在尝试检测 NFC 标签的制造商名称 我找到了制造商代码here 但我只能使用这些 ID 检测 Mifare Ultralight C 标签 Ultralight C 标签 ID 的第一个字节代表制造商代码 但其他标签不包含此属性 Th
  • Typescript:通用类型“提取具有 X 类型值的键”的行为不符合预期

    我定义了以下泛型类型 它从类型 T 中提取值为数字的字符串键 type StringKeysMatchingNumber
  • href="tel:" 和手机号码

    如果我使用tel 我应该写国际电话代码 就像这样 a href 61709 a 到目前为止 一切都很好 但我找不到有关如何以 国际 方式书写手机号码的信息 如果有的话 拨打您所在国家 地区的号码时 您仍然需要拨打国内长途电话号码在其余数字之
  • 使用 Xampp 运行 Python 脚本

    我正在使用 python 2 7 13首先 浏览器显示原始代码 我做了什么 编辑httpd conf AddHandler cgi script cgi pl asp py 在我所有脚本的顶部我添加了以下内容 j Installeds Py
  • C# 和 LINQ:按嵌套查询的值对查询进行排序

    我正在 ASP NET 中编写一个简单的论坛 该论坛位于 C 的实体框架数据库之上 Each Topic对象具有导航属性Posts指向一个集合Post对象 每个Post对象有一个属性When这表明该帖子的发布时间 Post Parent是类
  • 如何防止winforms设计器将Text属性设置为实例名称

    在开始之前 似乎以前可能有人问过类似 相同的问题here 然而没有明确的答案 假设我有一个自定义 winforms 控件 它覆盖Text财产 public class MyControl Control DefaultValue publi
  • 使用 ASP.NET 表单身份验证的 WCF 服务

    我正在通过 jQuery ajax 从 ASP NET 页面调用 WCF Web 服务 NET 4 0 如何保护 WCF 服务的安全 以便只有经过身份验证的 ASP NET 用户才能调用该服务的方法 我是否需要在每个服务方法中强制手动检查表
  • Google AppEngine ImportError:动态模块未定义 init 函数 (init_mysql)

    当我在 Google AppEngine 上使用 Flask 部署 python 应用程序时 出现此错误 如果有人帮助我 我将不胜感激 ps 我的本地服务器工作得很好 File base data home apps s dwnup 997
  • 如何在 php 中获取会话 ID 或用户名?

    我有一个用户可以登录的网站 我尝试过
  • 带扩展名的 TypeScript 导入

    您可能听说过 Deno 它是一个新的 TypeScript 运行时 Deno 和普通 TypeScript 之间的一个主要区别是您必须在 import 语句中包含文件扩展名 例如 import foo from bar ts 我想编写与 D
  • css resize 属性 - 更改调整大小图标属性

    我有一个带有 调整大小 属性的 div 默认情况下 您只能通过拖动窗口的右下角来更改大小 我想知道是否有可能改变它的行为 例如它的外貌 size or position 具体来说 我想做的是允许用户在边缘 而不是角落 重新调整窗口的大小 类
  • mongo $slice查询反向索引超出范围

    mongo 中的以下查询表现得很奇怪 db items findOne List slice skip 3 第一的 它不是仅返回一个带有 id List 键的对象 而是返回一个完整的对象 第二 如果skip是负数并且 skip 高于 lis
  • Numpy 创建一个空的 alpha 图像

    我想创建一个空白的 alpha 图像来解析 py opencv 中的一些数据并将其保存在透明背景 png 文件中 我试过 blank image np zeros H W 4 np uint8 and blank image np full
  • 在异步方法中绑定到输出 Blob 时,将 Blob 绑定到 IAsyncCollector 时出错

    我正在尝试在这篇文章之后的异步方法中绑定到 blob 输出 如何将输出值绑定到我的异步 Azure Functions 我有多个输出绑定 因此仅返回不是一个选择 public static async Task
  • 在脚本中设置数字变量(“set $i 1”)不起作用(“echo $i”为空)

    正如标题所说 我需要一个 bash 脚本的帮助 该脚本必须在给定两个数字变量的情况下生成一个字符串 该字符串将用于生成文件名 但是当我测试名称生成代码时 它不会产生任何结果 脚本是下面的代码 usr bin set nombre decla
  • 以编程方式将数据源绑定到报表服务器中的 rdl - SSRS

    我已经完成了一个 ASP NET 应用程序来生成特定数据的报告 最初 我创建了本地报告 rdlc 来生成报告 我为每个 rdlc 创建了单独的 xsd 并设计了报告 我以编程方式构建数据集并将其绑定到 rdlc 我使用以下代码将数据源绑定到
  • 关联引用是如何实现的?

    我在这里看到了一个非常好的示例 子类 UIButton 添加属性 它是什么 您无法将对象添加到类别 但现在有了这个技巧你就可以了 那么它是什么 它是如何工作的 Objective c 对象已经有一些恒定数量的 ivar 指针 对吗 现在你再