说你
protocol Able: class {
var v:UIView? { get set }
var x:CGFloat { get set }
}
当然,当你使用 Able 时,
如果您忘记了“v”或“x”...
这是一个错误。那很好。
那么这样做:
class ScreenThing: UIViewController, Able {
@IBOutlet var v: UIView?
var x: CGFloat = 0.0
}
一切顺利。太好了。
强制指定“v”和“x”并实际初始化它们。
但是。试试这个...
var _H: UInt8 = 0
protocol Able: class {
}
extension Able where Self:UIViewController {
var p:P {
get {
return objc_getAssociatedObject(self, &_H) as! P
}
set {
objc_setAssociatedObject(self, &_H, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
__setter()
}
}
}
Able 现在有一个属性 p。
您可以在 Able 的函数或 ScreenThing 的函数中完美地使用 p。太好了。
然而……
当你这样做的时候......
class ScreenThing: UIViewController, Able {
}
您不会收到错误。
您可能会忘记初始化“p”(它会崩溃)。
事实上,您不必将“p”指定为变量(因为您必须指定“v”和“x”)。
为什么会这样?
这似乎是个大问题。
我是否需要做一些不同的事情来让编译器强制执行“p”,就像它通常强制执行协议(protocol)中的变量一样?
完全按照我上面的代码:
有没有办法强制编译器需要消费者类中“p”的初始值设定项?
例如。
我试过了...
class ScreenThing: UIViewController, Able {
var p:P
}
但这行不通。
(奇怪的是,编译 - 实际上我不知道它到底在做什么!它似乎是一个与扩展中的 p 不同的 p。但无论如何它不强制执行需要一个初始化程序。)
简而言之,上面有什么我可以做或添加的,这会让编译器强制我初始化伪属性的东西,就像我在协议(protocol)中放置一个属性时它通常会做的那样作为“x”或“v”。
?
(脚注 -- 请参阅 this 以了解上述协议(protocol)中所需的“: 类”。)
我上面的困惑是没有什么可以初始化。 var p:P 在扩展中(带有 get 和 set 代码块)只是两个函数。
没有什么要初始化的。
例如:在我的额外问题中,我问“如何强制符合类在唤醒时对其进行初始化?”那是没有意义的。如果有的话,人们可能会问:“如何强制符合类确保在唤醒时‘使用那些功能’?” - 这与初始化无关。
另请注意,我在计算变量中的特定示例代码恰好(无关地)使用了未初始化的变量 - 导致混淆。
最佳答案
你不必在协议(protocol)的采用者中实现p,因为协议(protocol)扩展已经提供了一个实现。这就是协议(protocol)扩展。
更简单的例子:
protocol P {}
extension P {
func greet() {print("hello")}
}
class C : P {}
C().greet()
请注意 (1) 即使 C 没有声明 greet 也会编译,(2) 即使 C 不包含 greet 的实现它也会运行。那是因为这是协议(protocol)扩展的工作。
关于ios - 协议(protocol)扩展似乎没有在消费者中强制执行变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41796998/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下