我正在将 swift 代码添加到现有的 Objective-C 项目中。我在从现有前缀 header 引用定义时遇到问题。
我有一个名为 MyClass 的类,它是在 Objective-C 中用 .h 定义的:
@interface MyClass
+(instancetype)myClass;
-(void)doStuff;
@end
和.m:
@implementation MyClass
+ (instancetype) myClass
{
// More to it than this, but this illustrates the setup
return [[MyClass alloc] init];
}
- (void)doStuff
{
// Do something interesting
}
@end
前缀 header MyProj-Prefix.pch 包含:
#define MYCLASS MyClass
#define SOMEVAR @"Hello"
我创建了一个桥接头,其中包含:
#import "MyProj-Prefix.pch"
该项目包含使用类定义的 Objective-C 代码,例如
[[MYCLASS myClass] doStuff];
我想在我的新 swift 代码中反射(reflect)这一点。我可以看到并引用定义的变量,但是定义的类不可见。例如
let someStr = SOMEVAR // This compiles
MYCLASS.myClass.doStuff() // MYCLASS isn't visible
关于如何实现这一目标的任何指示?我什至不确定这在 swift 中是否可行。
最佳答案
即使 #define MYCLASS MyClass 在任何其他 header 中,但不一定在前缀 header 中,这个问题也会存在。这是因为预处理器指令通常不会导入到 Swift 中。但是,如果可以将简单宏映射到全局常量,则导入简单宏,这对于 SOMEVAR 是可能的,但对于 MYCLASS 是不可能的。参见 https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-ID17 .
可以在全局范围内使用 Swift 中的类型别名:
typealias MYCLASS = MyClass
当然,如果在 header 中重新定义了 MYCLASS,则必须修改类型别名。
不幸的是,如果 MYCLASS 的定义根据代码构建的位置/方式发生变化,这种方法不是很有用。但是,由于代码必须对可定义为 MYCLASS 的各种类的共同行为有相当多的了解,因此可以在这里使用协议(protocol),例如。
更新:
在更多地考虑/玩它并阅读其他一些帖子之后,例如Using obj-c typedef in Swift ,我认为这是一个更好的解决方案。使用这种方法,如果 MYCLASS 在 Objective-C 中重新#defined,则无需更改 Swift 代码。
在您的 Objective-C 代码中的某处,例如在桥接头中,添加
typedef MYCLASS * _MYCLASS;
这将允许您在 Swift 中执行如下操作:
_MYCLASS.myClass().doStuff()
如果出于某种原因你真的坚持在 Swift 中使用 MYCLASS,在你的 Swift 代码中添加 typealias MYCLASS = _MYCLASS 就可以了。
关于objective-c - 在 swift 中从前缀 header 引用类定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47528183/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c