第一次约会尴尬跟女生接吻,为何下面会硬起来????搞得走路都有点尴尬😒😒&

url中的#、?、&_JavaScript_第七城市
url中的#、?、&
1. #& & 10年9月,twitter改版。一个显著变化,就是URL加入了&#!&符号。比如,改版前的用户主页网址为/username改版后,就变成了/#!/username  这是主流网站第一次将&#&大规模用于重要URL中。这表明井号(Hash)的作用正在被重新认识。本文根据HttpWatch的文章,整理与井号有关的所有重要知识点。一、#的涵义  #代表网页中的一个位置。其右面的字符,就是该位置的标识符。比如,/index.html#print就代表网页index.html的print位置。浏览器读取这个URL后,会自动将print位置滚动至可视区域。  为网页位置指定标识符,有两个方法。一是使用锚点,比如&a name=&print&&&/a&,二是使用id属性,比如&div id=&print&&。二、HTTP请求不包括#  #是用来指导浏览器动作的,对服务器端完全无用。所以,HTTP请求中不包括#。比如,访问下面的网址,/index.html#print,浏览器实际发出的请求是这样的:GET /index.html HTTP/1.1Host: &三、#后的字符  在第一个#后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端。比如,下面URL的原意是指定一个颜色值:/?color=#fff,但是,浏览器实际发出的请求是:GET /?color= HTTP/1.1Host: &  四、改变#不触发网页重载  单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。比如,从/index.html#location1改成/index.html#location2,浏览器不会重新向服务器请求index.html。&五、改变#会改变浏览器的访问历史  每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用&后退&按钮,就可以回到上一个位置。这对于ajax应用程序特别有用,可以用不同的#值,表示不同的访问状态,然后向用户给出可以访问某个状态的链接。值得注意的是,上述规则对IE 6和IE 7不成立,它们不会因为#的改变而增加历史记录。  六、window.location.hash读取#值  window.location.hash这个属性可读可写。读取时,可以用来判断网页状态是否改变;写入时,则会在不重载网页的前提下,创造一条访问历史记录。  七、onhashchange事件  这是一个HTML 5新增的事件,当#值发生变化时,就会触发这个事件。IE8+、Firefox 3.6+、Chrome 5+、Safari 4.0+支持该事件。  它的使用方法有三种:window.onhashchange =&body onhashchange=&func();&&window.addEventListener(&hashchange&, func, false);  对于不支持onhashchange的浏览器,可以用setInterval监控location.hash的变化。八、Google抓取#的机制  默认情况下,Google的网络蜘蛛忽视URL的#部分。  但是,Google还规定,如果你希望Ajax生成的内容被浏览引擎读取,那么URL中可以使用&#!&,Google会自动将其后面的内容转成查询字符串_escaped_fragment_的值。  比如,Google发现新版twitter的URL:/#!/username  就会自动抓取另一个URL:/?_escaped_fragment_=/username  通过这种机制,Google就可以索引动态的Ajax内容。&注AJAX&= 异步&JavaScript和XML(标准通用标记语言的子集)。AJAX&是一种用于创建快速动态网页的技术。回到顶部2. ?1)连接作用:比如/Show.asp?id=77&nameid=&page=12)清除缓存:比如/index.html /index.html?test123123两个url打开的页面一样,但是后面这个有问号,说明不调用缓存的内容,而认为是一个新地址,重新读取。回到顶部3. &不同参数的间隔符参考文章:/kaituorensheng/p/3776527.html/blog/2011/03/url_hash.html
最新教程周点击榜
微信扫一扫作者:Mike Ash,原文链接,原文日期:译者:riven;校对:Cee;定稿:千叶知风即便你已经在火星的一个洞穴里,紧闭着你的双眼并且捂住你的耳朵,也避免不了 Swift 已经开源的事实。正因为开源,我们能够更加方便地去探索 Swift 中的很多有趣的特性,其中之一便是 Swift 中弱引用是如何工作的问题。弱引用在采用垃圾回收器或者引用计数进行内存管理的语言中,强引用可以使得特定的对象一直存活,但弱引用就无法保证。当一个对象被强引用时,它是不能够被销毁的;但是如果它是个弱引用,就可以。当我们所提到「弱引用」时,通常的意思是指一个归零弱引用(Zeroing Weak Reference)。也就是说,当弱引用的目标对象被销毁时,弱引用就会变成 nil(校者注:看这篇文章了解更多)。非归零弱引用也是存在的,它会导致一些陷阱(Trap)、崩溃(Crash)或者未定义行为的调用。比如你在 Objective-C 中使用 unsafe_unretained,或者在 Swift 中使用 unowned(Objective-C 未定义行为处理方式,而 Swift 却很可靠地处理这些崩溃)。归零弱引用很方便使用,在基于引用计数进行内存管理的语言中他们是非常有用的。它们允许循环引用存在却不会产生死循环,并且不需要手动打破逆向引用。他们非常的有用,在苹果引入 ARC 和让弱引用在垃圾收集代码之外的语言层面上可用之前,我就已经实现了我自己的弱引用版本。它是如何工作的呢?归零弱引用比较典型的实现方式是保持一个对每个对象的所有弱引用列表。当对一个对象创建了弱引用,这个引用就会被添加到这个列表中。当这个引用被重新赋值或者超出了其作用域,它就会从列表中被移除。当一个对象被销毁,这个列表中的所有引用都会被归零。在多线程的情况下,其实现必须是同步获取一个弱引用并销毁一个对象,以避免竞态条件的出现:比如当一个线程释放某个对象的最后一个强引用而同时另一个线程却试图加载一个它的一个弱引用。在我的实现中,每一个弱引用都是一个完整的对象。弱引用列表是一个弱引用对象的集合。虽然由于额外的转换和内存使用让效率变低了,但这种方式可以很方便的让这些引用变成完整的对象。苹果公司的 Objective-C 的实现是这样的,每一个弱引用是一个指向目标对象的普通指针。编译器并不直接读写指针,而是使用一些帮助函数。当存储一个弱指针时,存储函数会将指针的位置注册为目标对象的一个弱引用。由于读取函数被集成进了引用计数系统,这就确保了在读取一个弱指针时,不会返回一个已经被释放了的对象的指针。归零操作让我们创建一些代码来研究一下它们究竟是怎么运行的。我们希望写一个函数能够 dump 一个对象的内存内容。这个函数接受一块内存区域,将其按指针大小进行分块,并且将最终的结果转换成一个易于查看的十六进制字符串:func contents(ptr: UnsafePointer&Void&, _ length: Int) -& String {let wordPtr = UnsafePointer&UInt&(ptr)let words = length / sizeof(UInt.self)let wordChars = sizeof(UInt.self) * 2let buffer = UnsafeBufferPointer&UInt&(start: wordPtr, count: words)let wordStrings = buffer.map({ word -& String invar wordString = String(word, radix: 16)while wordString.characters.count & wordChars {wordString = "0" + wordString}return wordString})return wordStrings.joinWithSeparator(" ")}下一个函数会为一个对象创建一个 dump 函数。调用时传入一个对象,它会返回一个 dump 这个对象内容的函数。在函数内部,我们给对象保存了一个 UnsafePointer,而不是普通的引用。这样可以确保它不会和语言的引用计数系统发生交互。它允许我们可以在这个对象被销毁之后 dump 出它的内存,后面我们会介绍。func dumperFunc(obj: AnyObject) -& (Void -& String) {let objString = String(obj)let ptr = unsafeBitCast(obj, UnsafePointer&Void&.self)let length = class_getInstanceSize(obj.dynamicType)return {let bytes = contents(ptr, length)return "/(objString) /(ptr): /(bytes)"}}下面是一个包含弱引用变量的类,后面我会观察这个弱引用。我在弱引用变量的前后分别添加了一个 dummy 变量,以便于我们区分弱引用在 dump 出来的内存结构中的位置:class WeakReferer {var dummy1 = 0x3210weak var target: WeakTarget?var dummy2: UInt = 0xabcdefabcdefabcd}让我们试一下! 我们先创建一个引用,然后 dump 它:let referer = WeakReferer()let refererDump = dumperFunc(referer)print(refererDump())打印结果:WeakReferer 0x1b920: ab24a0 00 abcdefabcdefabcd我们看到 isa 指针位于最开始的位置,紧随其后的是其它一些内部字段。dummy1 变量占据了第四块,dummy2 变量占据了第六块。正如我们所期望的那样,在他们之间的弱引用正好是零。现在我们让这个弱引用指向一个目标对象,看看会变成什么样。我将这段代码放入一个 do语句中,以便于当目标对象超出作用域和被销毁时我们可以进行控制:do {let target = NSObject()referer.target = targetprint(target)print(refererDump())}打印结果:&NSObject: 0x7fda6a21c6a0&WeakReferer 0x00007fda6a000ad0: a44a0 007fda6a21c6a0 abcdefabcdefabcd正如我们期望的那样,目标对象的指针直接存储在弱引用中。在目标对象被销毁之后,我们在 do 代码块之后再次调用 dump 函数:print(refererDump())WeakReferer 0x00007ffe0000010cfb44a0 00 abcdefabcdefabcd它被归零了。点个赞!仅仅为了好玩,我们用一个纯 Swift 对象作为对象来重复这个实验。不必要时,我并不是很想使用 Objective-C 中的东西。下面是一个纯 Swift 对象:class WeakTarget {}让我们试一下:let referer = WeakReferer()let refererDump = dumperFunc(referer)print(refererDump())do {class WeakTarget {}let target = WeakTarget()referer.target = targetprint(refererDump())}print(refererDump())目标对象像我们期望的那样被归零了,然后被重新赋值:WeakReferer 0x00007fbea0 00 abcdefabcdefabcdWeakReferer 0x00007fbea0 007fbe95121ce0 abcdefabcdefabcd然后当目标对象被销毁,引用应该被归零:WeakReferer 0x00007fbea0 007fbe95121ce0 abcdefabcdefabcd不幸的是它并没有被归零。可能是目标对象没有被销毁。一定是有某些东西让它继续活着!让我们再检查一下:class WeakTarget {deinit { print("WeakTarget deinit") }}再次运行代码,结果如下:WeakReferer 0x0fa10: ae44a0 00 abcdefabcdefabcdWeakReferer 0x0fa10: ae44a0 007fd29a42a920 abcdefabcdefabcdWeakTarget deinitWeakReferer 0x0fa10: ae44a0 007fd29a42a920 abcdefabcdefabcd它消失了,但是弱引用并没有归零。怎么回事呢,我们发现了 Swift 的一个 bug!很神奇,这个 bug 一直没有被解决。你会想之前肯定已经有人已经注意到了这个问题。接下来,我们通过访问弱引用来产生一个崩溃,然后我们可以用这个 Swift 工程提交这个 bug :let referer = WeakReferer()let refererDump = dumperFunc(referer)print(refererDump())do {class WeakTarget {deinit { print("WeakTarget deinit") }}let target = WeakTarget()referer.target = targetprint(refererDump())}print(refererDump())print(referer.target)下面就是崩溃信息:WeakReferer 0x0d060: a04a0 00 abcdefabcdefabcdWeakReferer 0x0d060: a04a0 007ff7aa2157f0 abcdefabcdefabcdWeakTarget deinitWeakReferer 0x0d060: a04a0 007ff7aa2157f0 abcdefabcdefabcdnil哦,我的天呐!大爆炸在哪呢?应该有一个惊天动地的大爆炸呀!输出的内容表明一切工作正常,但我们可以清楚地从 dump 内容看到它并没有正常工作。让我们再仔细检查一下。下面是一个经过修改的 WeakTarget 类,我们添加了一个 dummy 变量以便于区分 dump 的内容:class WeakTarget {var dummy = 0xabcdefdeinit {print("Weak target deinit")}}下面是一段新的代码,运行的程序和之前的基本相同,只不过每次 dump 都会输出两个对象(校者注:Target 和 Referer):let referer = WeakReferer()let refererDump = dumperFunc(referer)print(refererDump())let targetDump: Void -& Stringdo {let target = WeakTarget()targetDump = dumperFunc(target)print(targetDump())referer.target = targetprint(refererDump())print(targetDump())}print(refererDump())print(targetDump())print(referer.target)print(refererDump())print(targetDump())让我们检查一下输出内容。referer 对象的生命周期和之前一样,它的 target 字段被顺利的归零了:WeakReferer 0x0520: faa64a0 00 abcdefabcdefabcdtarget 首先作为一个普通对象,在各种头字段之后紧跟着我们的 dummy 字段:WeakTarget 0x0d270: faa63e0 789abcdef在给 target 字段赋值后,我们可以看到被填充的指针的值:WeakReferer 0x0520: faa64a0 007fe abcdefabcdefabcdtarget 对象还是和之前一样,但是它其中一个头字段增加了 2:WeakTarget 0x0d270: faa63e0 789abcdef目标对象像我们期望的那样被销毁了:Weak target deinit我们看到引用对象一直都有一个指针指向目标对象:WeakReferer 0x0520: faa64a0 007fe abcdefabcdefabcd并且目标对象本身一直存活着。和上次我们看到的相比,它的头字段减少了 2:WeakTarget 0x0d270: faa63e0 789abcdef访问 target 字段会产生 nil ,即便它没有被归零:nil再次 dump referer 对象的内容,从中我们看出仅仅访问 target 字段的行为已经改变了它。现在它被归零了:WeakReferer 0x0520: faa64a0 00 abcdefabcdefabcd目标对象现在被完全抹掉了:WeakTarget 0x0d270: 342a04 342811 ffffffffffff0002现在变的越来越有趣了。我们看到头字段会一会儿增加,一会儿减少;让我们看看是否能有重现出更多的信息:let target = WeakTarget()let targetDump = dumperFunc(target)do {print(targetDump())weak var a = targetprint(targetDump())weak var b = targetprint(targetDump())weak var c = targetprint(targetDump())weak var d = targetprint(targetDump())weak var e = targetprint(targetDump())var f = targetprint(targetDump())var g = targetprint(targetDump())var h = targetprint(targetDump())var i = targetprint(targetDump())var j = targetprint(targetDump())var k = targetprint(targetDump())}print(targetDump())打印结果:WeakTarget 0x0df0: aabcdefWeakTarget 0x0df0: aabcdefWeakTarget 0x0df0: aabcdefWeakTarget 0x0df0: aabcdefWeakTarget 0x0df0: aa3456789abcdefWeakTarget 0x0df0: ac3456789abcdefWeakTarget 0x0df0: ac3456789abcdefWeakTarget 0x0df0: acabcdefWeakTarget 0x0df0: ac3456789abcdefWeakTarget 0x0df0: ac3456789abcdefWeakTarget 0x0df0: ac3456789abcdefWeakTarget 0x0df0: acabcdefWeakTarget 0x0df0: aabcdef我们看到每一个新的弱引用会让头字段中的第一个数增加 2。每一个新的强引用会让头字段中的第二个数增加 4。回顾一下,下面这些就是目前我们所发现的:在内存中弱指针和普通指针是一样的.当一个弱目标对象(WeakTarget)的 deinit 方法调用时,目标对象是不会被释放的,并且弱指针也不会被归零。当目标对象的 deinit 方法执行之后,访问弱指针,它就会被归零并且弱目标对象也会被释放。弱目标对象包含一个弱引用的引用计数,与强引用计数分离开。Swift 代码既然 Swift 已经开源,我们可以通过查看源代码来继续我们的观察。在 Swift 标准库中用 HeapObject 类型来表示一个分配在堆上的对象,其实现可参考 stdlib/public/SwiftShims/HeapObject.h。看起来是这样的:cppstruct HeapObject {/// 这始终是一个有效的元数据对象的指针。struct HeapMetadata const *SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;// FIXME: 在 32 位的平台上分配了两个字大小的元数据。#ifdef __cplusplusHeapObject() =// 给新分配的堆内存初始化空间(对象alloc,是分配的堆内存)。constexpr HeapObject(HeapMetadata const *newMetadata) : metadata(newMetadata), refCount(StrongRefCount::Initialized), weakRefCount(WeakRefCount::Initialized){ }#endif};Swift 的 metadata 字段就相当于 Objective-C 的 isa 字段,并且它们是兼容的。还有一些像 NON_OBJC_MEMBERS 这样的宏定义:cpp#define SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS
StrongRefCount refC
WeakRefCount weakRefCount噢,快看!这就是我们的两个引用计数。(附加问题:为什么这里强引用在前面,而在 dump 时确是弱引用在前面?)引用计数是通过位于 stdlib/public/runtime/HeapObject.cpp 文件中的一系列函数来进行管理的。比如,下面的 swift_retain:cppvoid swift::swift_retain(HeapObject *object) {SWIFT_RETAIN();_swift_retain(object);}static void _swift_retain_(HeapObject *object) {_swift_retain_inlined(object);}auto swift::_swift_retain = _swift_retain_;这里面拐了几个弯,但它最终是调用头文件中的内联函数:cppstatic inline void _swift_retain_inlined(HeapObject *object) {
if (object) {object-&refCount.increment();
}}如你所见,它会增加引用计数。下面是 increment 函数的实现:cppvoid increment() {
__atomic_fetch_add(&refCount, RC_ONE, __ATOMIC_RELAXED);}RC_ONE 来自于一个枚举类型:cppenum : uint32_t {
RC_PINNED_FLAG = 0x1,
RC_DEALLOCATING_FLAG = 0x2,
RC_FLAGS_COUNT = 2,
RC_FLAGS_MASK = 3,
RC_COUNT_MASK = ~RC_FLAGS_MASK,
RC_ONE = RC_FLAGS_MASK + 1};相信你已经明白为什么每一个新的强引用会让头字段增加 4 了吧。这个枚举类型的前两位用来作为标志位。回想一下之前的 dump 结果,我们可以看到这些标志位。下面是一个弱目标对象在最后一个强引用消失之前和之后的结果:WeakTarget 0x0d270: faa63e0 789abcdefWeak target deinitWeakTarget 0x0d270: faa63e0 789abcdef其中第二个字段开始是 4,表示引用计数为 1 并且没有标志位,之后变成了 2,表示引用计数为 0 和 RC_DEALLOCATING_FLAG 标志位被设定了。这个被析构的对象被放在了处于 DEALLOCATING 状态的位置。(顺便说一句,RC_PINNED_FLAG 到底是用来干什么的呢?我查找了相关代码,除了能够表明一个「固定的对象(pinned object)」外,其它对于这个标记一无所知。如果你弄清楚了或者有一些相关的猜测,请给我留言。)现在让我们看一看弱引用计数的实现。它有同样的枚举结构:cppenum : uint32_t {
// There isn't really a flag here.
// Making weak RC_ONE == strong RC_ONE saves an
// instruction in allocation on arm64.
RC_UNUSED_FLAG = 1,
RC_FLAGS_COUNT = 1,
RC_FLAGS_MASK = 1,
RC_COUNT_MASK = ~RC_FLAGS_MASK,
RC_ONE = RC_FLAGS_MASK + 1};这就是 2 的来源:其中有一个保留的标志位,目前尚未被使用。奇怪的是,关于这段代码的注释似乎是不正确的,这的 RC_ONE 等于 2,而强引用的 RC_ONE 等于 4。我猜它们曾经是相等的,但后来它被修改了而注释却没有更新。我只是想表明如果注释是无用的,那你为什么还要写它呢。所有这些是如何和加载弱引用相关联的呢?它是由 swift_weakLoadStrong 函数来处理的:cppHeapObject *swift::swift_weakLoadStrong(WeakReference *ref) {
auto object = ref-&V
if (object == nullptr)
if (object-&refCount.isDeallocating()) {swift_weakRelease(object);ref-&Value =
return swift_tryRetain(object);}从上面的代码,惰性归零是如何工作的已经一目了然了。当加载一个弱引用时,如果目标对象正在被销毁,就会对这个引用进行归零。反之,会保留目标对象并返回它。进一步深挖一点,我们可以看到 swift_weakRelease 如何释放对象的内存,前提是它是最后一个引用:cppvoid swift::swift_weakRelease(HeapObject *object) {
if (!object)
if (object-&weakRefCount.decrementShouldDeallocate()) {// 只有对象可以 weak-retained 和 weak-releasedauto metadata = object-&assert(metadata-&isClassObject());auto classMetadata = static_cast&const ClassMetadata*&(metadata);assert(classMetadata-&isTypeMetadata());swift_slowDealloc(object, classMetadata-&getInstanceSize(),
classMetadata-&getInstanceAlignMask());
}}(注意:如果你正在查看版本库中的代码,使用「weak」命名的地方大多数都改成了「unowned」。上面的命名是截至撰写本文时最新的快照,但开发仍在继续。你可以查看和我这对应的版本库中的 2.2 版本的快照,或者获取最新的版本但是要注意命名的变化,并且实现也有可能发生了改变。)整合我们已经在层级上自上往下地看到了 Swift 中的弱引用是如何实现的。那么在高层观察 Swift 的弱引用又是如何工作的呢?弱引用只是指向目标对象的指针。在 Objective-C 中是没有办法单独追踪弱引用的。相反,每一个 Swift 对象都有一个弱引用计数,和它的强引用计数相邻。Swift 将对象的析构过程(deinit)和对象的释放(dealloc)解耦。一个对象可以被析构并释放它的外部资源,但不必释放对象本身所占用的内存。当一个 Swift 对象的强引用计数变成零而弱引用计数仍大于零时,那么这个对象会被析构,但是不会被释放。这意味着一个被释放对象的弱指针仍然是一个有效的指针,它可以被反向引用而不会崩溃或者加载垃圾数据。它们只是指向一个处于僵尸状态的对象。当一个弱引用被加载时,运行时会检查目标对象的状态。如果目标对象是一个僵尸对象,然后它会对弱引用进行归零,也就是减少弱引用计数并返回 nil。当僵尸对象的所有弱引用都被归零,那么这个僵尸对象就会被释放。比起 Objective-C 中的实现,这种设计会带来一些有趣的结果:不需要维护一个弱引用列表。这样既简化代码也提高了性能。在一个线程归零一个弱引用和另外一个线程加载一个弱引用之间就不会存在竞态条件了。这也意味着加载一个弱引用和销毁一个弱引用对象不需要加锁。这也提高了性能。一个对象即便没有了强引用,但是弱引用任然会导致该对象被分配的内存被占用,直到所有弱引用被加载或者被丢弃。这种做法临时增加了内存使用。但是要注意的是这个影响很小,当目标对象没有被释放时,它所占的内存大小只是实例本身。当最后一个强引用变成零时,所有的外部资源(包括用于存储的 Array 或 Dictionary 属性)都会被释放。弱引用会导致被分配的单个实例不会被释放,而不是整个对象树。每一个对象都需要额外的内存来存储弱引用计数。但在实际的 64 位系统中,这似乎是无关紧要的。头字段要占据所有指针大小的块的数量,并且强和弱引用计数共享一个头字段。如果没有弱引用计数,强引用计数就会占据整个 64 位。通过使用非指针(non-pointer) isa 可以将强引用移到 isa 中,但我不确定那是不是很重要或者它未来会如何发展。 对于 32 位系统,弱引用计数会将对象的大小增加四个字节。然而,32 位系统如今已经没有那么重要了.因为访问一个弱指针是如此的方便,所以 unowned 的语义也采用了相同的机制来实现。unowned 和 weak 工作方式是一样的,只是当目标对象被释放,unowned 会给你一个大大的失败,而不是给你返回一个 nil 。在 Objective-C 中,__unsafe_unretained 是作为一个带有未定义行为的原始指针来实现的,你可以快速的访问它,毕竟加载一个弱指针还是有点慢。总结Swift 的弱指针通过一种有趣的方式,既保证了速度和正确性,也保证较低的内存开销。通过追踪每个对象的弱引用计数,将对象的销毁和对象的析构过程分离开来,弱引用问题被安全而又快速的得到解决。正是由于可以查看标准库的源代码,这让我们可以在源代码级别看到究竟发生了什么,而不是像我们之前通过反编译和 dump 内存来进行研究。当然,正如你上面看到的那样,我们很难完全打破这个习惯。今天就这样了。下次回来会带来更多的干货。由于假期的缘故,可能需要几周,但是我会在之前发布一篇稍微短一点的文章。不管怎样,给接下来的话题提更多的建议吧。周五问答是由读者们的想法驱动的,如果你有一个你希望了解的想法,请告知我!本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权,最新文章请访问 http://swift.gg。
无相关信息
最新教程周点击榜
微信扫一扫百度拇指医生
&&&普通咨询
您的网络环境存在异常,
请输入验证码
验证码输入错误,请重新输入百度拇指医生
&&&普通咨询
您的网络环境存在异常,
请输入验证码
验证码输入错误,请重新输入百度拇指医生
&&&普通咨询
您的网络环境存在异常,
请输入验证码
验证码输入错误,请重新输入}

我要回帖

更多关于 新娘接吻呕吐尴尬 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信