【问题标题】:Subclassing NSCalendar?子类化 NSCalendar?
【发布时间】:2010-08-19 21:44:05
【问题描述】:

我正在尝试创建 NSCalendar 的子类,但运气不佳。我尝试了两种方法:

  1. 完整的类别。我可以创建一个修改过的对象和一个我添加的测试方法(不是 NSCalendar 的一部分)工作得很好,但覆盖的方法不起作用 - 例如如果我调用 dateFromComponents:,显然调用的是 NSCalendar 方法,而不是我在类别定义中写的

  2. 常规子类。在这种情况下,我什至无法创建实例:initWithCalendarIdentifier 引发 _CFRequireConcreteImplementation 异常。最初我只在子类中重写了几个方法,但后来我重写了所有(记录在案的)NSCalendar 方法 - 结果是一样的。

甚至可以继承 NSCalendar 吗?

我想这样做的原因是使用非标准重复间隔重复本地通知。默认功能允许本地通知重复每个 [日历单位],但我需要不规则的间隔 - 例如我可以通过间隔 15 分钟创建 4 个“每小时”通知来模拟“每 15 分钟”通知,但我需要它们在 T+20、T+22、T+24、T+44、T+46 时触发, T+66 分钟以此类推(T 是开始时间)- 通知之间的间隔是 20 分钟,然后是 2 分钟,然后是 20 分钟,以此类推。

我希望,由于 UILocalNotification 想要一个 NSCalendar(在 repeatCalendar 属性中)来计算何时触发下一个通知,我可以通过覆盖 dateFromComponents 来实现我想要的,只返回 [NSDate dateWithIntervalSinceNow] 间隔交替20 和 2 分钟 - 但我的狡猾计划似乎有一个大问题,因为无法继承 NSCalendar。

编辑:当应用程序在后台时,需要这整件事。在前台我使用计时器,就像没有人特别建议的那样。

【问题讨论】:

    标签: iphone


    【解决方案1】:

    即使您确实设法继承了 NSCalendar,我也怀疑它会起作用。我强烈怀疑本地通知是由 SpringBoard 安排的,我认为它不会在每次需要查看下一个触发日期时启动/恢复您的应用程序。

    第一步是找出什么 UILocalNotification 对你的日历做了什么。最简单的方法是编写一个 NSObject 子类,它转发未定义的方法调用并打印日志消息(respondsToSelector:、methodSignatureForSelector:、forwardInvocation:)。一般来说,你想要像if ([super respondsToSelector:selector]) { return [super ...]; } else { return [target ...]; } 这样的东西。

    那么,最简​​单的 hack 就是编写一个类来实现 NSCalendar 的必要方法以满足您的目的。

    您也可以考虑拨打[super init]-[NSCalendar initWithCalendarIdentifier:] 可能会返回不同的 self(例如 [self release]; return [[NSGregorianCalendar alloc] init]),而您不希望这样。你传递的是什么日历标识符?也许它抱怨它需要一个“具体的实现”,它知道你传递的日历标识符。

    【讨论】:

    • 创建一个 NSobject 子类看起来是个好主意,谢谢!它看起来它 正在 以某种方式被使用,因为当我实际上给它喂食 NSObject 派生而不是 NSCalendar 时,出现了一个相当奇怪的模拟器崩溃 :) 我过去常常给它传递一个普通的公历,什么都没有花哨(而且我不在乎使用什么日历)
    【解决方案2】:

    从 NSCalendar 直接继承很棘手,因为我认为它是一个类集群。我对这个概念有点模糊,所以我会给你一个指向 Apple 文档的链接,而不是自欺欺人。

    http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW34

    【讨论】:

      【解决方案3】:

      尝试使用 NSTimer 方法

      + (NSTimer *)scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
      

      将重复设置为 TRUE 并具有 2 分钟的时间间隔。有一个您设置为 1 或 10 的计数器。每次调用选择器时,您都会递减计数器,直到您完成工作并重置计数器时它达到 0。

      【讨论】:

      • NSTimer 很酷,但不能在后台工作(我需要它作为后台) - 抱歉,我好像不太清楚。
      • 当你的应用在后台暂停时定时器不会运行,这是重复本地通知的全部意义。
      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多