NSTimer Category + Blocks 实现替换选择器

2023-12-06

我对块和 Objective-C 很陌生,我正在尝试使用两者来编写我的第一个类别。我的想法是在 NSTimer 上创建一个类别,它将接收一个块作为参数,并且该块将在选择器调用中使用。现在我有这个。

// NSTimer+Additions.h

#import <Foundation/Foundation.h>

typedef void (^VoidBlock)();

@interface NSTimer (NSTimer_Additions)


+ (NSTimer *)scheduleTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions;
@end

#import "NSTimer+Additions.h"

static VoidBlock _voidBlock;

@interface NSTimer (AdditionsPrivate) // Private stuff
- (void)theBlock;
@end


@implementation NSTimer (NSTimer_Additions)


+ (NSTimer *)scheduleTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions {

    [_voidBlock release];
    _voidBlock = [actions copy];

    NSTimer* timer = [[NSTimer alloc] initWithFireDate:[NSDate date] 
                                          interval:theSeconds
                                            target:self 
                                          selector:@selector(theBlock) 
                                          userInfo:nil 
                                           repeats:repeats];
    [timer fire];

    return [timer autorelease];
}


- (void)theBlock {
    _voidBlock();
}

@end

代码要点:https://gist.github.com/1065235

一切都编译正常,但我有以下错误:

2011-07-05 14:35:47.068 TesteTimer[37716:903]*由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“+[NSTimer theBlock]:无法识别的选择器发送到类 0x7fff70bb0a18”

我怎样才能让这个类别发挥作用?


除了错误的目标之外,您的主要缺陷是您使用了静态变量。您将无法支持超过一个计时器。

使用块作为调用方法的参数。

@interface NSTimer (AdditionsPrivate) // Private stuff
- (void)theBlock:(VoidBlock)voidBlock;
@end


@implementation NSTimer (NSTimer_Additions)

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions {
    NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:[self instanceMethodSignatureForSelector:@selector(theBlock:)]];
    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:theSeconds
                                                   invocation:invocation
                                                      repeats:repeats];
    [invocation setTarget:timer];
    [invocation setSelector:@selector(theBlock:)];
    
    Block_copy(actions);
    [invocation setArgument:&actions atIndex:2];
    Block_release(actions);

    return timer;
}


- (void)theBlock:(VoidBlock)voidBlock {
    voidBlock();
}

@end

使用关联引用的问题是泄漏,因为没有释放块的好点。


使用关联引用的早期方法

您可以使用associative references将块附加到该特定实例NSTimer.

@implementation NSTimer (NSTimer_Additions)

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions {
    NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:[self instanceMethodSignatureForSelector:@selector(theBlock)]];
    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:theSeconds
                                                   invocation:invocation
                                                      repeats:repeats];
    [invocation setTarget:timer];
    [invocation setSelector:@selector(theBlock)];

    objc_setAssociatedObject(timer, @"Block", actions, OBJC_ASSOCIATION_COPY);
    
    return timer;
}


- (void)theBlock {
    VoidBlock _voidBlock = (VoidBlock)objc_getAssociatedObject(self, @"Block");
    _voidBlock();
}

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

NSTimer Category + Blocks 实现替换选择器 的相关文章

  • 设置使用 iPhone 相机拍摄的图像的类型

    如果我们使用 iPhone 相机拍摄照片 图像将默认以 JPEG 格式保存 我想以其他格式 例如 PNG 保存捕获的图像 是否可以 当我们从应用程序调用 iPhone 相机时 是否可以通过代码执行此操作 我们可以设置捕获图片后必须保存的图像
  • iOS UITableViewCell需要按两次才能调用didSelectRowAtIndexPath

    我有一个 UITableView 有时需要您触摸它两次才能选择一个单元格 更多细节 仅当表格一直向上或一直向下滚动后才需要两次触摸 只需第二次触摸即可呼叫didSelectRowAtIndexPath 当表格以自然的 向上滚动位置 打开时
  • 核心蓝牙在后台进行广告和扫描

    我一直在尝试设置一个应用程序 使设备既扫描外围设备又作为外围设备进行广告 目标是当两个设备通过蓝牙发现彼此靠近时在后台被唤醒 从 Apple 文档来看 您似乎应该能够在后台运行 BLE 启用蓝牙中心和蓝牙外设后台模式 并且当一台设备位于前台
  • 如何在 Monotouch 中对 UIImageView 进行运动模糊效果?

    在 MonoTouch 中进行实时运动模糊的方法是什么 当滚动惯性图片库时 我需要在 UIImageView 上应用运动模糊效果 以强度和方向作为参数 就像在 Photoshop 中一样 我在 CocoaTouch 或 CoreAnimat
  • 应用程序在第二次运行 nsnull 计数的循环时崩溃

    我有一个循环 第一次运行正常 但第二次循环时我得到 NSNull count unrecognized selector sent to instance 0x3a094a70 Terminating app due to uncaught
  • CoreAnimation 性能分析 - CAReplicatorLayer 与 CAShapeLayer

    我正在制作一个依赖 CoreAnimation 的应用程序 它有一个 CAReplicatorLayer 和一个 CAShapeLayer 作为子层 当进行 12 次复制 然后对路径进行动画处理 在 touchMoved 上更改它 时 一旦
  • CNContact 添加新的联系人问题

    我在通过以下方式添加联系人时遇到问题联系框架 我使用的是装有 iOS 12 1 2 的 iPhone 5s 设备 我添加联系人的代码如下 let saveRequest CNSaveRequest saveRequest add self
  • Xcode 不会在故事板中显示我的文本字段占位符文本

    当我在属性检查器中分配文本字段的占位符值时 它不会显示在故事板中 但是 当我运行应用程序的模拟器时 它就在那里 我缺少什么设置吗 我只想能够在编辑器中看到占位符文本 下面是 xcode 和模拟器之一的屏幕截图 我遇到了同样的问题 幸运的是我
  • Swift 3 '[UIApplicationLaunchOptionsKey:任意]?'无法转换为 '[String : NSString]'

    我有一个 TVOS 应用程序已从 Swift 2 转换为 Swift 3 但出现以下错误 我不确定如何让它安静下来 UIApplicationLaunchOptionsKey 任意 无法转换为 String NSString 它出现在这段代
  • 使用 JavaScript 从 URL 变量读取来加载不同的 CSS 样式表

    我试图在我的 WordPress 博客上使用两个不同的样式表 以便在通过 Web 访问页面时使用一个样式表 而在通过我们的 iOS 应用程序访问博客内容时使用另一个样式表 现在 我们将 app true 附加到来自 iOS 应用程序的 UR
  • 自动调整大小完成后如何获取帧大小

    我想知道 如何以及何时 viewDidLoad viewWillAppear viewDidAppear 可以获得自动调整大小以适合其父视图的 UIViews 框架大小 从你的问题中不清楚你为什么想要它 但我想这是为了布局你的子视图 幸运的
  • 使用 UIImagePickerController 的应用程序在拍照后选择“使用照片”时冻结

    我现在正在开发一个简单的照片和视频捕获应用程序 该应用程序成功地允许用户按下按钮即可拍摄照片或视频 但是 一旦您完成拍摄照片或视频 它就会提供 2 个选项 重新拍摄 和 使用照片 或 使用视频 具体取决于您使用的选项 如果用户点击 重新拍摄
  • 尝试从独立的 Apple Watch 应用发出网络请求

    当应用程序是独立应用程序时 Apple Watch 是否无法进行网络通话 即使手表已连接到 iPhone 我正在使用新的独立应用程序目标 它没有附带可以发出 WatchConnectivity 请求的配对 iOS 应用程序 我十有八九收到
  • 如何从 NSString 中删除十六进制字符

    我面临一个与字符串中的某些十六进制值相关的问题 我需要从字符串中删除十六进制字符 The problem is when i print object it prints as BLANK line And in debug mode it
  • 切换到工作区并在 Xcode 中添加 CocoaPods 后提交 git 吗?

    我刚刚在 Xcode 5 中将 CocoaPods 添加到我当前的项目中 当然 CocoaPods 创建了一个工作区 并且我已在 Xcode 中启动了该工作区 我在工作区中看到了我的项目和 Pods 项目 我的项目从第一天起就处于源代码控制
  • 从 RemoteIO 保存音频的示例?

    我进行了搜索 但没有找到任何从 RemoteIO 音频单元保存音频的好示例或教程 我的设置 使用 MusicPlayer API 我有几个 AUSamplers gt MixerUnit gt RemoteIO 音频播放效果很好 我想添加将
  • swift 中的负数模

    负数模如何在 swift 中工作 当我执行 1 3 时 它给出 1 但余数是 2 其中有什么问题 雨燕余数运算符 计算余数 整数除法 a b a a b b where 是截断整数除法 在你的情况下 1 3 1 1 3 3 1 0 3 1
  • 如何在 Xcode 4 中通过一个操作归档多个目标

    我有一个包含多个目标的项目 这些目标都适用于不同的 iOS 应用程序 例如 一个用于精简版的目标 另一个用于专业版的目标 我想立即构建并归档我的所有应用程序 目前 我对每个目标都有一个方案 我用它来独立归档每个应用程序 但现在我必须开始归档
  • 播放(非库)Apple Music 内容 - 请求失败

    我正在尝试使用以下代码播放专辑 let predicate MPMediaPropertyPredicate value 1459938538 forProperty MPMediaItemPropertyAlbumPersistentID
  • 当设置 setVisibleXRangeMaximum 时,iOS-Charts X 轴值无限重复

    我正在尝试绘制一个图表 其中 x 轴是TimeIntervalY 轴是power consumption 由于每天都会有数据 因此将有太多数据无法显示 因此 我想一次显示 5 个值 我通过设置实现了这一点self chart setVisi

随机推荐

  • Python 逆字母顺序

    我有这个输出 3 one 2 was 2 two 1 too 1 racehorse 1 a 我需要将具有相同编号的元组按相反的字母顺序放置在列表中 这是我的代码 def top5 words text split text text sp
  • html body ondblclick 获取被点击的元素

    所以在我的 html 中我有这部分 div dasd div div dasda div 在 javascript 中 该函数是 function myfunc do stuff here 我想知道在 myfunc 内部 html 主体的哪
  • 在 Get-ChildItem 中指定 *.xls 过滤器也会返回 *.xlsx 结果

    我有一个包含 xls xlsx 和 xlsm 文件的文件夹 并且想仅过滤 xls 文件 为什么以下行不能按我的预期工作 我看到 xls xlsx 和 xlsm 结果 Get ChildItem Get Location Filter xls
  • 验证错误消息有效时不会隐藏

    更新2 我发现输入的标题由于某种原因被显示为错误消息 我使用忽略标题 true以确保标题不会显示为错误消息 However 现在我的新问题是 一旦我输入有效的电子邮件地址 错误消息仍然不会消失 如何修复验证错误消息 使其在输入字段有效时隐藏
  • Ionic2 的字体很棒

    如何使用 Font Awesome 图标
  • 有没有办法判断传入的变量是引用类型还是值类型?

    在Swift中 有没有办法通过代码判断传入的变量是引用类型还是值类型 例如 元组是值类型还是引用类型 一切是一个值类型 除了 一个类的实例 一个功能 一个数组 其工作方式很奇怪 它通过引用传递 但如果它是可变的并且项目数量发生更改 则可以与
  • 如何找到加载缓慢的 SAPUI5 应用程序的加载瓶颈

    我正在构建一个自定义 SAPUI5 应用程序 其中包含七个图表 sap viz ui5 controls VizFrame 在页面的标题内容中 嵌套在sap suite ui commons ChartContainer 和网格表 sap
  • 脚本循环遍历目录中的文件

    我有以下代码 它使用我需要的数据从 shp file 创建我需要的 txt 文件 我有一个名为 profile 的文件夹 其中包含一些名为 profil1 shp profil2 shp profil3 shp 等 的形状文件 我想知道如何
  • 如何在Spring-kafka中实现ConsumerSeekAware?

    我正在尝试使用 KafkaListener 实现消费者 我正在使用Spring2 3 7版本 这是到目前为止我的代码 public class SampleListener KafkaListener topics test topic c
  • 从命令行编译适用于 iOS 9 的 C 库,Xcode 7-beta 2

    我在使用最新的 Xcode 7 beta clang 编译适用于 iOS 9 的 C 库 gmp 时遇到问题 我正在尝试生成位码以使 Xcode 中的所有警告停止 并且我想以位码生成这些库 但是 我什至无法首先编译该库 configure
  • MonoTouch:在 Retina 显示屏上调整色调时外观图像尺寸加倍

    我正在使用此代码设置导航栏的背景 该代码在视网膜和非视网膜显示器中效果很好 有一个 2x 和普通图像 所以 一切都好 UINavigationBar Appearance SetBackgroundImage GetImage ImageT
  • Web 服务 - Xml 包含在派生类而不是基类中?

    我使用抽象类作为 Web 服务调用中的参数 目前 我在基类中包含派生类的 XmlInclude 如下所示 XmlInclude typeof DerivedClass public abstract class BaseClass 但是 我
  • 暂停 python 脚本等待按键

    我有一个相对简单的脚本和一个可能简单的问题 在互联网上 我收集了一些关于如何使用直接按键作为 python 代码中的输入的解决方案 我更喜欢这些而不是 raw input 因为它感觉更快 就像如果我有一个包含 3 个选项的菜单 并且每个选项
  • 将 cmd 构建到 Tkinter 窗口中

    您好 我想知道启动程序时是否可以将命令提示符框弹出到 Tkinter 窗口中 就像是 from Tkinter import admin Tk cmd Cmd admin cmd pack admin mainloop 我在窗户上 http
  • Gitflow:将版本错误修复合并回 master 进行开发

    我的问题是围绕 gitflow 流程中的一个非常具体的点 如文档所述here 我已经合并了错误修复release 1 2 into master 并进行适当标记 除了历史看起来如何之外 反向合并与release 1 2与从后合并master
  • 我如何从views.py编辑/更改模型字段的值

    今天是个好日子 我想知道如何通过定义的会话列表中的项目数更改模型字段的值 我已经制作了一个配置文件模型 这是用户模型的 OneToOne Field 在我的 models py 中有一个 级别 字段 如下所示 在 view py 中 我创建
  • P文本添加到html文本中

    我知道这方面有很多主题 而且我已经查看了所有主题 但其中没有一个解决方案适用于我 我在页面编辑器的 文本 一侧放置了一个短代码来运行响应式滑块的 jscript 然而 当我加载页面时 源代码在每一行 JavaScript 后面都有大量的段落
  • 我应该在 Flutter 插件的 Swift 本机代码中传递哪个视图控制器?

    我试图在我的 Flutter 插件中显示来自 Swift 本机代码的 Adcolony 广告 这就是我的 swift 代码的样子 if let interstitial self interstitial interstitial expi
  • MacOS:以编程方式查找串行端口?

    MacOS 中是否有库调用来列出可用的串行端口及其设置 希望有一天能以最小的难度移植到 iOS 上 我宁愿不system ls dev tty and system stty 如果可能的话 您可以使用 IOKit 调用来查找串行端口 See
  • NSTimer Category + Blocks 实现替换选择器

    我对块和 Objective C 很陌生 我正在尝试使用两者来编写我的第一个类别 我的想法是在 NSTimer 上创建一个类别 它将接收一个块作为参数 并且该块将在选择器调用中使用 现在我有这个 NSTimer Additions h im