我已经设置了一个协议,将一些信息发送回上一个VC。
我这样定义:
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
但使用时有什么区别:
protocol FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?)
}
我什么时候应该使用: class
协议?
答案 0 :(得分:45)
AnyObject
添加到像这样的协议定义
protocol FilterViewControllerDelegate: AnyObject {
func didSearch(parameters:[String: String]?)
}
表示只有一个类能够符合该协议。
所以给出了这个
protocol FilterViewControllerDelegate: AnyObject {
func didSearch(parameters:[String: String]?)
}
你可以写这个
class Foo: FilterViewControllerDelegate {
func didSearch(parameters:[String: String]?) { }
}
但是不这个
struct Foo: FilterViewControllerDelegate {
func didSearch(parameters:[String: String]?) { }
}
:class
添加到像这样的协议定义
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
表示只有一个类能够符合该协议。
所以给出了这个
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
你可以写这个
class Foo: FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?) { }
}
但是不这个
struct Foo: FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?) { }
}
答案 1 :(得分:16)
还有一个关于使用'标记协议的另一个问题是'关键字。
这是你的协议:
#to check that the target has loaded its images, run images loaded
#after a small timeout to allow the page to get the images
#append a marker div to the dom if the images have successfully loaded
imagesLoadedScript = "var item = document.querySelector('#{csspath}');
window.scroll(0, item.offsetTop);
function imagesDone(path, fn) {
imagesLoaded( path, function(instance) {
console.log('PHANTOM CLIENT REPORTING: ' + path + ' Images Loaded');
fn(true);
})
}
setTimeout(function(){
imagesDone('#{csspath}', function(done) {
var markerDiv = document.createElement('div');
markerDiv.id = 'ImagesLoadedMarker';
document.getElementsByTagName('html')[0].appendChild(markerDiv);
});
}, 1000)"
#then we strip the new lines and spaces that we added to make it readable
imagesLoadedScript = imagesLoadedScript.strip.gsub(/\s+/,' ')
#now we just execute the script as we do not need a return value
@session.execute_script(imagesLoadedScript)
#then we check for the marker, using capybara's inbuilt waiting time
if @session.has_xpath? "//*[@id ='ImagesLoadedMarker']"
Rails.logger.debug "!!!!! PhantomClient: Images Loaded Reporting: #{csspath} Images Loaded: Check Time #{Time.now} !!!!!"
@session.save_screenshot(file_path, :selector => csspath)
else
Rails.logger.debug "!!!!! PhantomClient: Images Loaded Reporting: #{csspath} Images NOT Loaded: Check Time #{Time.now} !!!!!"
@session.save_screenshot(file_path, :selector => csspath)
end
例如,我们假设您正在创建一个具有委托属性的DetailVC:
protocol FilterViewControllerDelegate: class {
func didSearch(Parameters:[String: String]?)
}
如果你没有用“课程”标记该协议。关键字,您也无法标记该代表'作为“弱者”的财产之一。
为什么?
这很简单 - 只有基于类的属性可能会有弱关系。 如果你试图避免参考周期,那就是要走的路了
答案 2 :(得分:7)
protocol FilterViewControllerDelegate: AnyObject {
func didSearch(Parameters:[String: String]?)
}
该协议只能由类采用。
回答您的第一个问题 -
但使用时有什么区别:
与此不同的是:
protocol FilterViewControllerDelegate {
func didSearch(Parameters:[String: String]?)
}
是该协议可以采用值类型,例如枚举和结构。
回答您的第二个问题 -
我什么时候应该使用:class protocal?
当您应该使用类协议时,我想从委托模式描述下一个示例: 想象一下,你有委托协议。
protocol PopupDelegate: AnyObject {
func popupValueSelected(value: String)
}
并在另一个类中创建属性
var delegate: PopupDelegate?
但这有一个强大的参考,可以带来内存泄漏的问题。修复内存泄漏的一种方法是使委托属性 - 弱。在我们不能使我们的协议仅用于申请课程之前,Swift认为我们也可以将我们的协议应用于价值类型。
weak var delegate: PopupDelegate?
如果您尝试将您的委托声明为弱,则会看到下一个错误:
'weak'var仅适用于类和类绑定协议类型, 不是'PopupDelegate'
但是我们不能将弱值应用于值类型。所以我们需要将协议限制为引用类型,因此swift知道它是一个引用类型。 为了使您可以将此委托声明为弱,您需要限制仅由类使用的协议:
protocol PopupDelegate: AnyObject {
func popupValueSelected(value: String)
}
答案 3 :(得分:5)
这意味着您定义的协议只能通过类,而不是结构或枚举来使用。
protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
// class-only protocol definition goes here }
在上面的示例中,SomeClassOnlyProtocol只能由类类型采用。它是 编写结构或枚举定义的编译时错误 试图采用SomeClassOnlyProtocol。
答案 4 :(得分:1)
Swift 3.2更新:
现在声明只有类协议写:
protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
// class-only protocol definition goes here
}
而不是
protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
// class-only protocol definition goes here
}
第二个片段现在似乎仍然有用。 参考:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html