如何使用 @selector 和 NSInvocation 从另一个对象调用 NSManaged 对象的 @dynamic 方法?
Posted
技术标签:
【中文标题】如何使用 @selector 和 NSInvocation 从另一个对象调用 NSManaged 对象的 @dynamic 方法?【英文标题】:How do I call NSManaged object's @dynamic method from from another object using a @selector and NSInvocation? 【发布时间】:2009-10-15 01:59:04 【问题描述】:这里是可可新手。我正在开发一个基于 iPhone UITableViewController 的小部件,该小部件可用于在启动期间编辑对象集中的日期和文本属性。目前,我正在尝试使用@selector 和 NSInvocation 来执行此操作,如下所示。 注意:“targetObject”是控制器初始化时设置的对象。
- (IBAction)saveDate:(id)sender
//The selector below would normally be passed in when the controller is initialized
[self setDoneSelector:@selector(setDate:)];
NSMethodSignature * sig = nil;
sig = [[targetObject class] instanceMethodSignatureForSelector:[self doneSelector]];
NSInvocation * myInvocation = nil;
myInvocation = [NSInvocation invocationWithMethodSignature:sig];
[myInvocation setTarget:targetObject];
[myInvocation setSelector:doneSelector];
NSDate * myDate = [datePicker date];
[myInvocation setArgument:&myDate atIndex:2];
NSString * result = nil;
[myInvocation retainArguments];
[myInvocation invoke];
这在大多数对象上都可以正常工作,但是在将核心数据 (NSManagedObject) 作为 targetObject 传递时遇到了麻烦。对象如下所示:
事务.h
#import <CoreData/CoreData.h>
@interface Transaction : NSManagedObject
@property (nonatomic, retain) NSString * message;
@property (nonatomic, retain) NSDate * date;
@end
交易.m
#import "Transaction.h"
@implementation Transaction
@dynamic message;
@dynamic date;
@end
如果我在控制器中将此对象设置为目标对象,我可以直接调用“setDate:”方法而不会出现问题。
[targetObject setDate:[datePicker date]];
但是当我尝试使用@selector 调用它时,我得到'程序接收信号:“EXC_BAD_ACCESS
”。'
我想这与 NSManagedObject 中使用的 @dynamic 方法以及它们的创建时间有关,但我对该过程知之甚少,不知道如何或是否可以解决此问题以使其正常工作。我已经尝试在 Transaction 对象中显式创建“setDate:(NSDate *)aDate”方法,并且该方法有效,但我想知道我是否应该这样做以及如何使用 NSManagedObject。
我可以在不明确定义的情况下使用@selector 访问这些setter 方法吗?
【问题讨论】:
为什么需要为此使用 NSInvocation? 澄清一下:NSObject 的 performSelector 系列消息在哪些方面不足以满足您的需求?很少有人需要使用 NSInvocation,我看不出有什么理由让你成为这个 sn-p 中的一员。 【参考方案1】:在这里与 NSD 达成一致。您应该首先将此代码简化为更简单的-performSelector:withObject:
版本:
- (IBAction)saveDate:(id)sender
[self.targetObject performSelector:self.doneSelector withObject:[self.datePicker date]];
如果仍然有问题,我们可以开始调试真正的问题所在。 NSInvocation
是解决这类简单问题的一个非常花哨的对象。
如果您仍然遇到崩溃,那么您需要查看实际的堆栈跟踪,以了解哪些变量未正确初始化或过度释放。
【讨论】:
第二。并且 EXEC_BAD_ACCESS 几乎总是在已释放的对象上调用方法。 (也许是一个超过其托管对象上下文或其他东西的指针?) 哇,我不敢相信我没有深入挖掘来找到更简单的方法。它看起来过于复杂,但我被锁定在 NSInvocation 上。此方法似乎可以消除 EXC_BAD_ACCESS 错误。简单、优雅、实用。我喜欢!谢谢大家。以上是关于如何使用 @selector 和 NSInvocation 从另一个对象调用 NSManaged 对象的 @dynamic 方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift #selector 语法解决“歧义使用”编译错误?
如何让 SYCL“default_selector”选择 Intel GPU 而不是 NVIDIA GPU?