1.iOS大解密:玄之又玄的KVO
导读:
大多数 iOS 开发人员对 KVO 的认识只局限于 isa 指针交换这一层,而 KVO 的实现细节却鲜为人知。
如果自己也仿照 KVO 基础原理来实现一套类 KVO 操作且独立运行时会发现一切正常,然而一旦你的实现和系统的 KVO 实现同时作用在同一个实例上那么各种各样诡异的 bug 和 crash 就会层出不穷。
这究竟是为什么呢?此类问题到底该如何解决呢?接下来我们将尝试从汇编层面来入手以层层揭开 KVO 的神秘面纱……
1. 缘起 Aspects
SDMagicHook 开源之后很多小伙伴在问“SDMagicHook 和 Aspects 的区别是什么?”,我在 GitHub 上找到 Aspects 了解之后发现 Aspects 也是以 isa 交换为基础原理进行的 hook 操作,但是两者在具体实现和 API 设计上也有一些区别,另外 SDMagicHook 还解决了 Aspects 未能解决的 KVO 冲突难题。
1.1 SDMagicHook 的 API 设计更加友好灵活
SDMagicHook 和 Aspects 的具体异同分析见 https://github.com/larksuite/SDMagicHook/issues/3。
1.2 SDMagicHook 解决了 Aspects 未能解决的 KVO 冲突难题
在 Aspects 的 readme 中我还注意到了这样一条关于 KVO 兼容问题的描述:
SDMagicHook 会不会有同样的问题呢?测试了一下发现 SDMagicHook 果然也中招了,而且其实此类问题的实际情况要比 Aspects 作者描述的更为复杂和诡异,问题的具体表现会随着系统 KVO(以下简称 native-KVO)和自己实现的类 KVO(custom-KVO)的调用顺序和次数的不同而各异,具体如下:
- 先调用 custom-KVO 再调用 native-KVO,native-KVO 和 custom-KVO 都运行正常
- 先调用 native-KVO 再调用 custom-KVO,custom-KVO 运行正常,native-KVO 会 crash
- 先调用 native-KVO 再调用 custom-KVO 再调用 native-KVO,native-KVO 运行正常,custom-KVO 失效,无 crash
目前,SDMagicHook 已经解决了上面提到的各类问题,具体的实现方案我将在下文中详细介绍。
2. 从汇编层面探索 KVO 本质
想要弄明白这个问题首先需要研究清楚系统的 KVO 到底是如何实现的,而系统的 KVO 实现又相当复杂,我们该从哪里入手呢?想要弄清楚这个问题,我们首先需要了解下当对被 KVO 观察的目标属性进行赋值操作时到底发生了什么。这里我们以自建的 Test 类为例来说明,我们对 Test 类实例的 num 属性进行 KVO 操作:
当我们给 num 赋值时,可以看到断点命中了 KVO 类自定义的 setNum:的实现即_NSSetIntValueAndNotify 函数
那么_NSSetIntValueAndNotify 的内部实现是怎样的呢?我们可以从汇编代码中发现一些蛛丝马迹:
Foundation`_NSSetIntValueAndNotify:
0x10e5b0fc2 <+0>: pushq %rbp
-> 0x10e5b0fc3 <+1>: movq %rsp, %rbp
0x10e5b0fc6 <+4>: pushq %r15
0x10e5b0fc8 <+6>: pushq %r14
0x10e5b0fca <+8>: pushq %r13
0x10e5b0fcc <+10>: pushq %r12
0x10e5b0fce <+12>: pushq %rbx
0x10e5b0fcf <+13>: subq $0x48, %rsp
0x10e5b0fd3 <+17>: movl %edx, -0x2c(%rbp)
0x10e5b0fd6 <+20>: movq %rsi, %r15
0x10e5b0fd9 <+23>: movq %rdi, %r13
0x10e5b0fdc <+26>: callq 0x10e7cc882 ; symbol stub for: object_getClass
0x10e5b0fe1 <+31>: movq %rax, %rdi
0x10e5b0fe4 <+34>: callq 0x10e7cc88e ; symbol stub for: object_getIndexedIvars
0x10e5b0fe9 <+39>: movq %rax, %rbx
0x10e5b0fec <+42>: leaq 0x20(%rbx), %r14
0x10e5b0ff0 <+46>: movq %r14, %rdi
0x10e5b0ff3 <+49>: callq 0x10e7cca26 ; symbol stub for: pthread_mutex_lock
0x10e5b0ff8 <+54>: movq 0x18(%rbx), %rdi
0x10e5b0ffc <+58>: movq %r15, %rsi
0x10e5b0fff <+61>: callq 0x10e7cb472 ; symbol stub for: CFDictionaryGetValue
0x10e5b1004 <+66>: movq 0x36329d(%rip), %rsi ; "copyWithZone:"
0x10e5b100b <+73>: xorl %edx, %edx
0x10e5b100d <+75>: movq %rax, %rdi
0x10e5b1010 <+78>: callq *0x2b2862(%rip) ; (void *)0x000000010eb89d80: objc_msgSend
0x10e5b1016 <+84>: movq %rax, %r12
0x10e5b1019 <+87>: movq %r14, %rdi
0x10e5b101c <+90>: callq 0x10e7cca32 ; symbol stub for: pthread_mutex_unlock
0x10e5b1021 <+95>: cmpb $0x0, 0x60(%rbx)
0x10e5b1025 <+99>: je 0x10e5b1066 ; <+164>
0x10e5b1027 <+101>: movq 0x36439a(%rip), %rsi ; "willChangeValueForKey:"
0x10e5b102e <+108>: movq 0x2b2843(%rip), %r14 ; (void *)0x000000010eb89d80: objc_msgSend
0x10e5b1035 <+115>: movq %r13, %rdi
0x10e5b1038 <+118>: movq %r12, %rdx
0x10e5b103b <+121>: callq *%r14
0x10e5b103e <+124>: movq (%rbx), %rdi
0x10e5b1041 <+127>: movq %r15, %rsi
0x10e5b1044 <+130>: callq 0x10e7cc2b2 ; symbol stub for: class_getMethodImplementation
0x10e5b1049 <+135>: movq %r13, %rdi
0x10e5b104c <+138>: movq %r15, %rsi
0x10e5b104f <+141>: movl -0x2c(%rbp), %edx
0x10e5b1052 <+144>: callq *%rax
0x10e5b1054 <+146>: movq 0x364385(%rip), %rsi ; "didChangeValueForKey:"
0x10e5b105b <+153>: movq %r13, %rdi
0x10e5b105e <+156>: movq %r12, %rdx
0x10e5b1061 <+159>: callq *%r14
0x10e5b1064 <+162>: jmp 0x10e5b10be ; <+252>
0x10e5b1066 <+164>: movq 0x2b22eb(%rip), %rax ; (void *)0x00000001120b9070: _NSConcreteStackBlock
0x10e5b106d <+171>: leaq -0x68(%rbp), %r9
0x10e5b1071 <+175>: movq %rax, (%r9)
0x10e5b1074 <+178>: movl $0xc2000000, %eax ; imm = 0xC2000000
0x10e5b1079 <+183>: movq %rax, 0x8(%r9)
0x10e5b107d <+187>: leaq 0xf5d(%rip), %rax ; ___NSSetIntValueAndNotify_block_invoke
0x10e5b1084 <+194>: movq %rax, 0x10(%r9)
0x10e5b1088 <+198>: leaq 0x2b7929(%rip), %rax ; __block_descriptor_tmp.77
0x10e5b108f <+205>: movq %rax, 0x18(%r9)
0x10e5b1093 <+209>: movq %rbx, 0x28(%r9)
0x10e5b1097 <+213>: movq %r15, 0x30(%r9)
0x10e5b109b <+217>: movq %r13, 0x20(%r9)
0x10e5b109f <+221>: movl -0x2c(%rbp), %eax
0x10e5b10a2 <+224>: movl %eax, 0x38(%r9)
0x10e5b10a6 <+228>: movq 0x364fab(%rip), %rsi ; "_changeValueForKey:key:key:usingBlock:"
0x10e5b10ad <+235>: xorl %ecx, %ecx
0x10e5b10af <+237>: xorl %r8d, %r8d
0x10e5b10b2 <+240>: movq %r13, %rdi
0x10e5b10b5 <+243>: movq %r12, %rdx
0x10e5b10b8 <+246>: callq *0x2b27ba(%rip) ; (void *)0x000000010eb89d80: objc_msgSend
0x10e5b10be <+252>: movq 0x362f73(%rip), %rsi ; "release"
0x10e5b10c5 <+259>: movq %r12, %rdi
0x10e5b10c8 <+262>: callq *0x2b27aa(%rip) ; (void *)0x000000010eb89d80: objc_msgSend
0x10e5b10ce <+268>: addq $0x48, %rsp
0x10e5b10d2 <+272>: popq %rbx
0x10e5b10d3 <+273>: popq %r12
0x10e5b10d5 <+275>: popq %r13
0x10e5b10d7 <+277>: popq %r14
0x10e5b10d9 <+279>: popq %r15
0x10e5b10db <+281>: popq %rbp
0x10e5b10dc <+282>: retq
上面这段汇编代码翻译为伪代码大致如下:
typedef struct {
Class originalClass; // offset 0x0
Class KVOClass; // offset 0x8
CFMutableSetRef mset; // offset 0x10
CFMutableDictionaryRef mdict; // offset 0x18
pthread_mutex_t *lock; // offset 0x20
void *sth1; // offset 0x28
void *sth2; // offset 0x30
void *sth3; // offset 0x38
void *sth4; // offset 0x40
void *sth5; // offset 0x48
void *sth6; // offset 0x50
void *sth7; // offset 0x58
bool flag; // offset 0x60
} SDTestKVOClassIndexedIvars;
typedef struct {
Class isa; // offset 0x0
int flags; // offset 0x8
int reserved;
IMP invoke; // offset 0x10
void *descriptor; // offset 0x18
void *captureVar1; // offset 0x20
void *captureVar2; // offset 0x28
void *captureVar3; // offset 0x30
int captureVar4; // offset 0x38
} SDTestStackBlock;
void _NSSetIntValueAndNotify(id obj, SEL sel, int number) {
Class cls = object_getClass(obj);
// 获取类实例关联的信息
SDTestKVOClassIndexedIvars *indexedIvars = object_getIndexedIvars(cls);
pthread_mutex_lock(indexedIvars->lock);
NSString *str = (NSString *)CFDictionaryGetValue(indexedIvars->mdict, sel);
str = [str copyWithZone:nil];
pthread_mutex_unlock(indexedIvars->lock);
if (indexedIvars->flag) {
[obj willChangeValueForKey:str];
((void(*)(id obj, SEL sel, int number))class_getMethodImplementation(indexedIvars->originalClass, sel))(obj, sel, number);
[obj didChangeValueForKey:str];
} else {
// 生成block
SDTestStackBlock block = {};
block.isa = _NSConcreteStackBlock;
block.flags = 0xC2000000;
block.invoke = ___NSSetIntValueAndNotify_block_invoke;
block.descriptor = __block_descriptor_tmp;
block.captureVar2 = indexedIvars;
block.captureVar3 = sel;
block.captureVar1 = obj;
block.captureVar4 = number;
[obj _changeValueForKey:str key:nil key:nil usingBlock:&SDTestStackBlock];
}
}
这段代码的大致意思是说首先通过 object_getIndexedIvars(cls)获取到 KVO 类的 indexedIvars,如果 indexedIvars->flag 为 true 即开发者自己重写实现过 willChangeValueForKey:或者 didChangeValueForKey:方法的话就直接以 class_getMethodImplementation(indexedIvars->originalClass, sel))(obj, sel, number)的方式实现对被观察的原方法的调用,否则就用默认实现为 NSSetIntValueAndNotify_block_invoke 的栈 block 并捕获 indexedIvars、被 KVO 观察的实例、被观察属性对应的 SEL、赋值参数等所有必要参数并将这个 block 作为参数传递给 [obj _changeValueForKey:str key:nil key:nil usingBlock:&SDTestStackBlock]调用。 看到这里你或许会有个疑问:伪代码中通过 object_getIndexedIvars(cls)获取到的 indexedIvars 是什么信息呢?block.invoke = ___ NSSetIntValueAndNotify_block_invoke 又是如何实现的呢? 首先我们看下 NSSetIntValueAndNotify_block_invoke 的汇编实现:
Foundation`___NSSetIntValueAndNotify_block_invoke:
-> 0x10bf27fe1 <+0>: pushq %rbp
0x10bf27fe2 <+1>: movq %rsp, %rbp
0x10bf27fe5 <+4>: pushq %rbx
0x10bf27fe6 <+5>: pushq %rax
0x10bf27fe7 <+6>: movq %rdi, %rbx
0x10bf27fea <+9>: movq 0x28(%rbx), %rax
0x10bf27fee <+13>: movq 0x30(%rbx), %rsi
0x10bf27ff2 <+17>: movq (%rax), %rdi
0x10bf27ff5 <+20>: callq 0x10c1422b2 ; symbol stub for: class_getMethodImplementation
0x10bf27ffa <+25>: movq 0x20(%rbx), %rdi
0x10bf27ffe <+29>: movq 0x30(%rbx), %rsi
0x10bf28002 <+33>: movl 0x38(%rbx), %edx
0x10bf28005 <+36>: addq $0x8, %rsp
0x10bf28009 <+40>: popq %rbx
0x10bf2800a <+41>: popq %rbp
0x10bf2800b <+42>: jmpq *%rax
___NSSetIntValueAndNotify_block_invoke 翻译成伪代码如下:
void ___NSSetIntValueAndNotify_block_invoke(SDTestStackBlock *block) {
SDTestKVOClassIndexedIvars *indexedIvars = block->captureVar2;
SEL methodSel = block->captureVar3;
IMP imp = class_getMethodImplementation(indexedIvars->originalClass);
id obj = block->captureVar1;
SEL sel = block->captureVar3;
int num = block->captureVar4;
imp(obj, sel, num);
}
这个 block 的内部实现其实就是从 KVO 类的 indexedIvars 里取到原始类,然后根据 sel 从原始类中取出原始的方法实现来执行并最终完成了一次 KVO 调用。 我们发现整个 KVO 运作过程中 KVO 类的 indexedIvars 是一个贯穿 KVO 流程始末的关键数据,那么这个 indexedIvars 是何时生成的呢?indexedIvars 里又包含哪些数据呢?想要弄清楚这个问题,我们就必须从 KVO 的源头看起,我们知道既然 KVO 要用到 isa 交换那么最终肯定要调用到 object_setClass 方法,这里我们不妨以 object_setClass 函数为线索,通过设置条件符号断点来追踪 object_setClass 的调用,lldb 调试截图如下:
断点到 object_setClass 之后,我们再验证看下寄存器 rdi、rsi 里面的参数打印出来分别是<Test: 0x600003df01b0>、NSKVONotifying_Test
不错,我们现在已经成功定位到 KVO 的 isa 交换现场了,然而为了找到 KVO 类的生成的地方我们还需要沿着调用栈向前回溯,最终我们定位到 KVO 类的生成函数_NSKVONotifyingCreateInfoWithOriginalClass,其汇编代码如下:
Foundation`_NSKVONotifyingCreateInfoWithOriginalClass:
-> 0x10c557d79 <+0>: pushq %rbp
0x10c557d7a <+1>: movq %rsp, %rbp
0x10c557d7d <+4>: pushq %r15
0x10c557d7f <+6>: pushq %r14
0x10c557d81 <+8>: pushq %r12
0x10c557d83 <+10>: pushq %rbx
0x10c557d84 <+11>: subq $0x20, %rsp
0x10c557d88 <+15>: movq %rdi, %r14
0x10c557d8b <+18>: movq 0x2b463e(%rip), %rax ; (void *)0x000000011012d070: __stack_chk_guard
0x10c557d92 <+25>: movq (%rax), %rax
0x10c557d95 <+28>: movq %rax, -0x28(%rbp)
0x10c557d99 <+32>: xorl %eax, %eax
0x10c557d9b <+34>: callq 0x10c55b452 ; NSKeyValueObservingAssertRegistrationLockHeld
0x10c557da0 <+39>: movq %r14, %rdi
0x10c557da3 <+42>: callq 0x10c7752b8 ; symbol stub for: class_getName
0x10c557da8 <+47>: movq %rax, %r12
0x10c557dab <+50>: movq %r12, %rdi
0x10c557dae <+53>: callq 0x10c775ba0 ; symbol stub for: strlen
0x10c557db3 <+58>: movq %rax, %rbx
0x10c557db6 <+61>: addq $0x10, %rbx
0x10c557dba <+65>: movq %rbx, %rdi
0x10c557dbd <+68>: callq 0x10c775666 ; symbol stub for: malloc
0x10c557dc2 <+73>: movq %rax, %r15
0x10c557dc5 <+76>: leaq 0x29d604(%rip), %rsi ; _NSKVONotifyingCreateInfoWithOriginalClass.notifyingClassNamePrefix
0x10c557dcc <+83>: movq $-0x1, %rcx
0x10c557dd3 <+90>: movq %r15, %rdi
0x10c557dd6 <+93>: movq %rbx, %rdx
0x10c557dd9 <+96>: callq 0x10c77510e ; symbol stub for: __strlcpy_chk
0x10c557dde <+101>: movq $-0x1, %rcx
0x10c557de5 <+108>: movq %r15, %rdi
0x10c557de8 <+111>: movq %r12, %rsi
0x10c557deb <+114>: movq %rbx, %rdx
0x10c557dee <+117>: callq 0x10c775108 ; symbol stub for: __strlcat_chk
0x10c557df3 <+122>: movl $0x68, %edx
0x10c557df8 <+127>: movq %r14, %rdi
0x10c557dfb <+130>: movq %r15, %rsi
0x10c557dfe <+133>: callq 0x10c775762 ; symbol stub for: objc_allocateClassPair
0x10c557e03 <+138>: movq %rax, %rbx
0x10c557e06 <+141>: testq %rbx, %rbx
0x10c557e09 <+144>: je 0x10c557f17 ; <+414>
0x10c557e0f <+150>: movq %rbx, %rdi
0x10c557e12 <+153>: callq 0x10c775816 ; symbol stub for: objc_registerClassPair
0x10c557e17 <+158>: movq %r15, %rdi
0x10c557e1a <+161>: callq 0x10c7754ec ; symbol stub for: free
0x10c557e1f <+166>: movq %rbx, %rdi
0x10c557e22 <+169>: callq 0x10c77588e ; symbol stub for: object_getIndexedIvars
0x10c557e27 <+174>: movq %rax, %r15
0x10c557e2a <+177>: movq %r14, (%r15)
0x10c557e2d <+180>: movq %rbx, 0x8(%r15)
0x10c557e31 <+184>: movq 0x2b4748(%rip), %rdx ; (void *)0x000000010d7fd1f8: kCFCopyStringSetCallBacks
0x10c557e38 <+191>: xorl %edi, %edi
0x10c557e3a <+193>: xorl %esi, %esi
0x10c557e3c <+195>: callq 0x10c774778 ; symbol stub for: CFSetCreateMutable
0x10c557e41 <+200>: movq %rax, 0x10(%r15)
0x10c557e45 <+204>: movq 0x2b49e4(%rip), %rcx ; (void *)0x000000010d7f6bb8: kCFTypeDictionaryValueCallBacks
0x10c557e4c <+211>: xorl %edi, %edi
0x10c557e4e <+213>: xorl %esi, %esi
0x10c557e50 <+215>: xorl %edx, %edx
0x10c557e52 <+217>: callq 0x10c774454 ; symbol stub for: CFDictionaryCreateMutable
0x10c557e57 <+222>: movq %rax, 0x18(%r15)
0x10c557e5b <+226>: leaq -0x38(%rbp), %rbx
0x10c557e5f <+230>: movq %rbx, %rdi
0x10c557e62 <+233>: callq 0x10c775a3e ; symbol stub for: pthread_mutexattr_init
0x10c557e67 <+238>: movl $0x2, %esi
0x10c557e6c <+243>: movq %rbx, %rdi
0x10c557e6f <+246>: callq 0x10c775a44 ; symbol stub for: pthread_mutexattr_settype
0x10c557e74 <+251>: leaq 0x20(%r15), %rdi
0x10c557e78 <+255>: movq %rbx, %rsi
0x10c557e7b <+258>: callq 0x10c775a20 ; symbol stub for: pthread_mutex_init
0x10c557e80 <+263>: movq %rbx, %rdi
0x10c557e83 <+266>: callq 0x10c775a38 ; symbol stub for: pthread_mutexattr_destroy
0x10c557e88 <+271>: cmpq $-0x1, 0x3824a0(%rip) ; _NSKVONotifyingCreateInfoWithOriginalClass.onceToken + 7
0x10c557e90 <+279>: jne 0x10c557fa4 ; <+555>
0x10c557e96 <+285>: movq (%r15), %rdi
0x10c557e99 <+288>: movq 0x366528(%rip), %rsi ; "willChangeValueForKey:"
0x10c557ea0 <+295>: callq 0x10c7752b2 ; symbol stub for: class_getMethodImplementation
0x10c557ea5 <+300>: movb $0x1, %cl
0x10c557ea7 <+302>: cmpq 0x38248a(%rip), %rax ; _NSKVONotifyingCreateInfoWithOriginalClass.NSObjectWillChange
0x10c557eae <+309>: jne 0x10c557ec9 ; <+336>
0x10c557eb0 <+311>: movq (%r15), %rdi
0x10c557eb3 <+314>: movq 0x366526(%rip), %rsi ; "didChangeValueForKey:"
0x10c557eba <+321>: callq 0x10c7752b2 ; symbol stub for: class_getMethodImplementation
0x10c557ebf <+326>: cmpq 0x38247a(%rip), %rax ; _NSKVONotifyingCreateInfoWithOriginalClass.NSObjectDidChange
0x10c557ec6 <+333>: setne %cl
0x10c557ec9 <+336>: movb %cl, 0x60(%r15)
0x10c557ecd <+340>: movq 0x36715c(%rip), %rsi ; "_isKVOA"
0x10c557ed4 <+347>: leaq 0x1ff(%rip), %rdx ; NSKVOIsAutonotifying
0x10c557edb <+354>: xorl %ecx, %ecx
0x10c557edd <+356>: movq %r15, %rdi
0x10c557ee0 <+359>: callq 0x10c558057 ; NSKVONotifyingSetMethodImplementation
0x10c557ee5 <+364>: movq 0x365154(%rip), %rsi ; "dealloc"
0x10c557eec <+371>: leaq 0x1ef(%rip), %rdx ; NSKVODeallocate
0x10c557ef3 <+378>: xorl %ecx, %ecx
0x10c557ef5 <+380>: movq %r15, %rdi
0x10c557ef8 <+383>: callq 0x10c558057 ; NSKVONotifyingSetMethodImplementation
0x10c557efd <+388>: movq 0x36519c(%rip), %rsi ; "class"
0x10c557f04 <+395>: leaq 0x433(%rip), %rdx ; NSKVOClass
0x10c557f0b <+402>: xorl %ecx, %ecx
0x10c557f0d <+404>: movq %r15, %rdi
0x10c557f10 <+407>: callq 0x10c558057 ; NSKVONotifyingSetMethodImplementation
0x10c557f15 <+412>: jmp 0x10c557f84 ; <+523>
0x10c557f17 <+414>: cmpq $-0x1, 0x382409(%rip) ; _NSKVONotifyingCreateInfoWithOriginalClass.kvoLog + 7
0x10c557f1f <+422>: jne 0x10c557fbc ; <+579>
0x10c557f25 <+428>: movq 0x3823f4(%rip), %r14 ; _NSKVONotifyingCreateInfoWithOriginalClass.kvoLog
0x10c557f2c <+435>: movl $0x10, %esi
0x10c557f31 <+440>: movq %r14, %rdi
0x10c557f34 <+443>: callq 0x10c7758e2 ; symbol stub for: os_log_type_enabled
0x10c557f39 <+448>: testb %al, %al
0x10c557f3b <+450>: je 0x10c557f79 ; <+512>
0x10c557f3d <+452>: movq %rsp, %rbx
0x10c557f40 <+455>: movq %rsp, %rax
0x10c557f43 <+458>: leaq -0x10(%rax), %r8
0x10c557f47 <+462>: movq %r8, %rsp
0x10c557f4a <+465>: movl $0x8200102, -0x10(%rax) ; imm = 0x8200102
0x10c557f51 <+472>: movq %r15, -0xc(%rax)
0x10c557f55 <+476>: leaq -0x63f5c(%rip), %rdi
0x10c557f5c <+483>: leaq 0x296c1d(%rip), %rcx ; "KVO failed to allocate class pair for name %s, automatic key-value observing will not work for this class"
0x10c557f63 <+490>: movl $0x10, %edx
0x10c557f68 <+495>: movl $0xc, %r9d
0x10c557f6e <+501>: movq %r14, %rsi
0x10c557f71 <+504>: callq 0x10c7751aa ; symbol stub for: _os_log_error_impl
0x10c557f76 <+509>: movq %rbx, %rsp
0x10c557f79 <+512>: movq %r15, %rdi
0x10c557f7c <+515>: callq 0x10c7754ec ; symbol stub for: free
0x10c557f81 <+520>: xorl %r15d, %r15d
0x10c557f84 <+523>: movq 0x2b4445(%rip), %rax ; (void *)0x000000011012d070: __stack_chk_guard
0x10c557f8b <+530>: movq (%rax), %rax
0x10c557f8e <+533>: cmpq -0x28(%rbp), %rax
0x10c557f92 <+537>: jne 0x10c557fd4 ; <+603>
0x10c557f94 <+539>: movq %r15, %rax
0x10c557f97 <+542>: leaq -0x20(%rbp), %rsp
0x10c557f9b <+546>: popq %rbx
0x10c557f9c <+547>: popq %r12
0x10c557f9e <+549>: popq %r14
0x10c557fa0 <+551>: popq %r15
0x10c557fa2 <+553>: popq %rbp
0x10c557fa3 <+554>: retq
0x10c557fa4 <+555>: leaq 0x382385(%rip), %rdi ; _NSKVONotifyingCreateInfoWithOriginalClass.NSObjectIMPLookupOnce
0x10c557fab <+562>: leaq 0x2b9886(%rip), %rsi ; __block_literal_global.8
0x10c557fb2 <+569>: callq 0x10c7753d8 ; symbol stub for: dispatch_once
0x10c557fb7 <+574>: jmp 0x10c557e96 ; <+285>
0x10c557fbc <+579>: leaq 0x382365(%rip), %rdi ; _NSKVONotifyingCreateInfoWithOriginalClass.onceToken
0x10c557fc3 <+586>: leaq 0x2b982e(%rip), %rsi ; __block_literal_global
0x10c557fca <+593>: callq 0x10c7753d8 ; symbol stub for: dispatch_once
0x10c557fcf <+598>: jmp 0x10c557f25 ; <+428>
0x10c557fd4 <+603>: callq 0x10c775102 ; symbol stub for: __stack_chk_fail
翻译成伪代码如下:
typedef struct {
Class originalClass; // offset 0x0
Class KVOClass; // offset 0x8
CFMutableSetRef mset; // offset 0x10
CFMutableDictionaryRef mdict; // offset 0x18
pthread_mutex_t *lock; // offset 0x20
void *sth1; // offset 0x28
void *sth2; // offset 0x30
void *sth3; // offset 0x38
void *sth4; // offset 0x40
void *sth5; // offset 0x48
void *sth6; // offset 0x50
void *sth7; // offset 0x58
bool flag; // offset 0x60
} SDTestKVOClassIndexedIvars;
Class _NSKVONotifyingCreateInfoWithOriginalClass(Class originalClass) {
const char *clsName = class_getName(originalClass);
size_t len = strlen(clsName);
len += 0x10;
char *newClsName = malloc(len);
const char *prefix = "NSKVONotifying_";
__strlcpy_chk(newClsName, prefix, len);
__strlcat_chk(newClsName, clsName, len, -1);
Class newCls = objc_allocateClassPair(originalClass, newClsName, 0x68);
if (newCls) {
objc_registerClassPair(newCls);
SDTestKVOClassIndexedIvars *indexedIvars = object_getIndexedIvars(newCls);
indexedIvars->originalClass = originalClass;
indexedIvars->KVOClass = newCls;
CFMutableSetRef mset = CFSetCreateMutable(nil, 0, kCFCopyStringSetCallBacks);
indexedIvars->mset = mset;
CFMutableDictionaryRef mdict = CFDictionaryCreateMutable(nil, 0, nil, kCFTypeDictionaryValueCallBacks);
indexedIvars->mdict = mdict;
pthread_mutex_init(indexedIvars->lock);
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
bool flag = true;
IMP willChangeValueForKeyImp = class_getMethodImplementation(indexedIvars->originalClass, @selector(willChangeValueForKey:));
IMP didChangeValueForKeyImp = class_getMethodImplementation(indexedIvars->originalClass, @selector(didChangeValueForKey:));
if (willChangeValueForKeyImp == _NSKVONotifyingCreateInfoWithOriginalClass.NSObjectWillChange && didChangeValueForKeyImp == _NSKVONotifyingCreateInfoWithOriginalClass.NSObjectDidChange) {
flag = false;
}
indexedIvars->flag = flag;
NSKVONotifyingSetMethodImplementation(indexedIvars, @selector(_isKVOA), NSKVOIsAutonotifying, nil)
NSKVONotifyingSetMethodImplementation(indexedIvars, @selector(dealloc), NSKVODeallocate, nil)
NSKVONotifyingSetMethodImplementation(indexedIvars, @selector(class), NSKVOClass, nil)
});
} else {
// 错误处理过程省略......
return nil
}
return newCls;
}
通过_NSKVONotifyingCreateInfoWithOriginalClass 的这段伪代码你会发现我们之前频繁提到 indexedIvars 原来就是在这里初始化生成的。objc_allocateClassPair 在 runtime.h 中的声明为 Class _Nullable objc_allocateClassPair(Class _Nullable superclass, const char * _Nonnull name, size_t extraBytes) ,苹果对 extraBytes 参数的解释为“The number of bytes to allocate for indexed ivars at the end of the class and metaclass objects.”,这就是说当我们在通过 objc_allocateClassPair 来生成一个新的类时可以通过指定 extraBytes 来为此类开辟额外的空间用于存储一些数据。系统在生成 KVO 类时会额外分配 0x68 字节的空间,其具体内存布局和用途我用一个结构体描述如下:
typedef struct {
Class originalClass; // offset 0x0
Class KVOClass; // offset 0x8
CFMutableSetRef mset; // offset 0x10
CFMutableDictionaryRef mdict; // offset 0x18
pthread_mutex_t *lock; // offset 0x20
void *sth1; // offset 0x28
void *sth2; // offset 0x30
void *sth3; // offset 0x38
void *sth4; // offset 0x40
void *sth5; // offset 0x48
void *sth6; // offset 0x50
void *sth7; // offset 0x58
bool flag; // offset 0x60
} SDTestKVOClassIndexedIvars;
3. 如何解决 custom-KVO 导致的 native-KVO Crash
读到这里相信你对 KVO 实现细节有了大致的了解,然后我们再回到最初的问题,为什么“先调用 native-KVO 再调用 custom-KVO,custom-KVO 运行正常,native-KVO 会 crash”呢?我们还以上面提到过的 Test 类为例说明一下:
首先用 Test 类实例化了一个实例 test,然后对 test 的 num 属性进行 native-KVO 操作,这时 test 的 isa 指向了 NSKVONotifying_Test 类。然后我们再对 test 进行 custom-KVO 操作,这时我们的 custom-KVO 会基于 NSKVONotifying_Test 类再生成一个新的子类 SD_NSKVONotifying_Test_abcd,此时问题就来了,如果我们没有仿照 native-KVO 的做法额外分配 0x68 字节的空间用于存储 KVO 关键信息,那么当我们向 test 发送 setNum:消息然后 setNum:方法调用 super 实现走到了 KVO 的_NSSetIntValueAndNotify 方法时还按照 SDTestKVOClassIndexedIvars *indexedIvars = object_getIndexedIvars(cls)方式来获取 KVO 信息并尝试获取从中获取数据时发生异常导致 crash。
找到问题的根源之后我们就可以见招拆招,我们可以仿照 native-KVO 的做法在生成 SD_NSKVONotifying_Test_abcd 也额外分配 0x68 自己的空间,然后当要进行 custom-KVO 操作时将 NSKVONotifying_Test 的 indexedIvars 拷贝一份到 SD_NSKVONotifying_Test_abcd 即可,代码实现如下:
一般情况下在 native-KVO 的基础上再做 custom-KVO 的话拷贝完 native-KVO 类的 indexedIvars 到 custom-KVO 类上就可以了,而我们的 SDMagicHook 只做到这些还不够,因为 SDMagicHook 在生成的新类上以消息转发的形式来调度方法,这样一来问题瞬间就变得更为复杂。举例说明如下:
由于用到消息转发,我们会将 SD_NSKVONotifying_Test_abcd 的setNum:对应的实现指向_objc_msgForward,然后生成一个新的 SEL__sd_B_abcd_setNum:来指向其子类的原生实现,在我们这个例子中就是 NSKVONotifying_TestsetNum:实现的即void _NSSetIntValueAndNotify(id obj, SEL sel, int number)函数。当 test 实例收到setNum:消息时会先触发消息转发机制,然后 SDMagicHook 的消息调度系统会最终通过向 test 实例发送一个__sd_B_abcd_setNum:消息来实现对被 Hook 的原生方法的回调,而现在__sd_B_abcd_setNum:对应的实现函数正是void _NSSetIntValueAndNotify(id obj, SEL sel, int number),所以__sd_B_abcd_setNum:就会被作为 sel 参数传递到_NSSetIntValueAndNotify函数。然后当_NSSetIntValueAndNotify函数内部尝试从 indexedIvars 拿到原始类 Test 然后从 Test 上查找__sd_B_abcd_setNum:对应的方法并调用时由于找不到对应函数实现而发生 crash。为解决这个问题,我们还需要为 Test 类新增一个__sd_B_abcd_setNum:方法并将其实现指向setNum:的实现,代码如下:
至此,“先调用 native-KVO 再调用 custom-KVO,custom-KVO 运行正常,native-KVO 会 crash”这个问题就可以顺利解决了。
4. 如何解决 native-KVO 导致 custom-KVO 失效的问题
目前还剩下一个问题“先调用 native-KVO 再调用 custom-KVO 再调用 native-KVO,native-KVO 运行正常,custom-KVO 失效,无 crash”。为什么会出现这个问题呢? 这次我们依然以 Test 类为例,首先用 Test 类实例化了一个实例 test,然后对 test 的 num 属性进行 native-KVO 操作,这时 test 的 isa 指向了 NSKVONotifying_Test 类。然后我们再对 test 进行 custom-KVO 操作,这时我们的 custom-KVO 会基于 NSKVONotifying_Test 类再生成一个新的子类 SD_NSKVONotifying_Test_abcd,这时如果再对 test 的 num 属性进行 native-KVO 操作就会惊奇地发现 test 的 isa 又重新指向了 NSKVONotifying_Test 类然后 custom-KVO 就全部失效了。
WHY?!!原来 native-KVO 会持有一个全局的字典_NSKeyValueContainerClassForIsa.NSKeyValueContainerClassPerOriginalClass 以 KVO 操作的原类为 key 和 NSKeyValueContainerClass 实例为 value 存储 KVO 类信息。
这样一来,当我们再次对 test 实例进行 KVO 操作时,native-KVO 就会以 Test 类为 key 从 NSKeyValueContainerClassPerOriginalClass 中查找到之前存储的 NSKeyValueContainerClass 并从中直接获取 KVO 类 NSKVONotifying_Test 然后调用 object_setclass 方法设置到 test 实例上然后 custom-KVO 就直接失效了。
想要解决这个问题,我想到了两种思路:1.修改 NSKVONotifying_Test 相关 KVO 数据 2.hook 拦截系统的 setclass 操作。然后仔细一想方案 1 是不可取的,因为 NSKVONotifying_Test 的相关数据是被所有 Test 类的实例在进行 KVO 操作时共享的,任何改动都有可能对 Test 类实例的 KVO 产生全局影响。所以,我们就需要借助 FishHook 来 hook 系统的 object_setclass 函数,当系统以 NSKVONotifying_Test 为参数对一个实例进行 setclass 操作时,我们检查如果当前的 isa 指针是 SD_NSKVONotifying_Test_abcd 且 SD_NSKVONotifying_Test_abcd 继承自系统的 NSKVONotifying_Test 时就跳过此次 setclass 操作。
但是这样做还不够,因为 custom-KVO 采用了特殊的消息转发机制来调度被 hook 的方法,如果先进行 custom-KVO 然后在进行 native-KVO 就会导致被观察属性被重复调用。所以,我们在对一个实例进行首次 custom-KVO 操作之前先进行 native-KVO,这样一来就可以保证我们的 custom-KVO 的方法调度正常工作了。代码如下:
总结
KVO 的本质其实就是基于被观察的实例的 isa 生成一个新的类并在这个类的 extra 空间中存放各种和 KVO 操作相关的关键数据,然后这个新的类以一个中间人的角色借助 extra 空间中存放各种数据完成复杂的方法调度。
系统的 KVO 实现比较复杂,很多函数的调用层次也比较深,我们一开始不妨从整个函数调用栈的末端层层向前梳理出主要的操作路径,在对 KVO 操作有个大致的了解之后再从全局的角度正向全面分析各个流程和细节。我们正是借助这种方式实现了对 KVO 的快速了解和认识。
至此,一个良好兼容 native-KVO 的 custom-KVO 就全部完成了。回头来看,这个解决方案其实还是过于 tricky 了,不过这也只能是在 iOS 系统的各种限制下的无奈的选择了。我们不提倡随意使用类似的 tricky 操作,更多是想要通过这个例子向大家介绍一下 KVO 的本质以及我们分析和解决问题的思路。如果各位读者可以从中汲取一些灵感,那么这篇文章“倒也算是不负恩泽”,倘若大家可以将这篇文章介绍到的思路和方法用于处理自己开发中的遇到的各种疑难杂症“那便真真是极好的了”!
更多分享
开源 | Objective-C & Swift 最轻量级 Hook 方案
今日头条 Android '秒' 级编译速度优化
字节跳动分布式表格存储系统的演进
字节跳动自研强一致在线 KV&表格存储实践 – 上篇
字节跳动-飞书音视频Mobile团队
本团队主要服务于飞书音视频产品,在产品性能、稳定性等用户体验,研发流程,编译优化,架构方向上不断优化和深入探索,以满足产品快速迭代的同时,保持较高的用户体验。我们长期在上海招聘 Android / iOS以及全栈平台架构方向的同学,想深入交流或者需要部门内推、投递简历的可以联系邮箱: qiuzehui@bytedance.com (标题注明 : 字节跳动-飞书Mobile直推)。
欢迎关注字节跳动技术团队
2.木马“打劫”HTTPS站点,新闻娱乐购物网站均遭殃!
近年来,国内各大网站逐渐升级为HTTPS加密连接、甚至是全站HTTPS,以防止网站被篡改劫持、用户数据被监听等,在很大程度上提升了网站的安全性。但是一向被认为”安全可靠”的HTTPS安全传输协议也不是万能的,如果在客户端出现木马,也可被轻易劫持!
近期360互联网安全中心监测到一款专门劫持https的木马又开始活跃,在2017年,360互联网安全中心曾曝光过该病毒团伙,之后该团伙有所收敛,最近他们重出江湖,又开始大肆传播;来自360网络安全研究院的数据显示,HTTPS劫匪木马主要用于劫持控制的域名之一(erhaojie.com)的网络访问请求,近日顶峰单日超过190万次。
传播:
传播方式主要通过”小电影”网站,以及广告位诱导用户安装:
劫持木马安装过程和之前版本没有太大区别,在此不再赘述。
《”移花接木”偷换广告:HTTPS劫匪木马每天打劫200万次网络访问》(https://www.freebuf.com/articles/system/144490.html)
危害:
劫持多达48个主流站点:
木马更新了导入其签发的证书,新增了15个域名,签发域名达到48个:
导入的证书及证书信息截图
符合域名规则的js文件请求,在js文件的尾部都会被插入用于劫持的js文件: hxxp://ssl.erhaojie.com/ssl/ba.js
Kangle Web后台看到的回应控制配置的劫持信息
劫持客户端新闻弹窗:
由于近年来软件弹mini新闻窗的风靡,软件作者也是新增了对mini窗页面的劫持,多个软件的mini窗均被劫持到带其推广ID的东方头条mini页面(http://mini.eastday.com/?qid=shxg, http://hot.eastday.com/mini065)
劫持mini页部分代码片断
微博账号刷粉:
此次木马还增加了微博账号自动加粉的功能,如果检测到用户电脑有登录微博则会对其内置的两个微博帐号进行自动点击添加关注:这两个微博粉丝均已超过7000个(其中一个帐号只发了4条微博),对比发现两个微博的粉丝基本相似,关注方式也基本一致;也能从侧面印证这两个微博帐号很大可能都是被通过这种方式添加的粉丝。
(一分钟看点)weibo.com/p/1005056585391017
(加V 看点新闻图)weibo.com/p/1005051729979622
劫持京东网页二维码:
将京东购物网站中,原本扫描安装京东客户端的二维码篡改为安装其推广软件!
劫持替换京东app的二维护码代码片断及截图
除上面介绍的两个恶意功能外,木马还能够:
1. 访问购物、导航、搜索等网站时,自动跳转带有作者推广号的网址。
2. 对访问的网站插入浮窗广告。
3. 替换掉原来网页中的广告内容。
4. 在搜索引擎的结果中插入广告。
由于这个恶意软件本身劫持功能做的不够精细,还会造成用户在访问网络时出现各种故障,比如:腾讯游戏的相关网站被劫持后,验证码输入窗口被跳转到东方头条网站,导致用户无法正常登录WeGame,如下图所示:
幕后作者:
分析过程中,我们发现这又是一起公司形式制作恶意软件的案例。
通过该劫持木马所用到的两个主要云控域名的备案信息及Whois信息,我们查出注册者为li**qun,邮箱为(30****28@qq.com) 公司为:深圳市**信息科技有限公司
备案信息显示,域名属于深圳某公司:
网站备案信息以及公司股权控制图
通过支付宝姓名验证也确认该邮箱对应的真实姓名为李*群
从搜索引擎搜索该QQ,也能看一些早年作者曾经发过网站备案相关的帖子以及制作过小电影网站的一些信息:
所有相关信息都指向同一主体:姓名(李*群)、及其公司:深圳市**信息科技有限公司、深圳****国际文化传播有限公司、手机1(158******69)、手机2(186******47)、QQ(30****28)、邮箱1(30****28@qq.com)、邮箱2(41*****84@qq.com);360互联网安全中心已将相关信息提交主管部门。
结语:
HTTPS的普及,很大程度上提升了网站的安全性,但HTTPS并不是万能的,也存在多种劫持和攻击的手段。近期更是有多款木马开始讲攻击目标锁定在https的站点上。现在绝大部分登录认证,支付过程等涉及用户敏感信息的操作均已经全部使用HTTPS的连接解决,针对HTTPS的劫持攻击,对用户的威胁也更大。用户和厂商也应格外注意此类型攻击。
对于此类木马,只要正常开启360安全卫士,遇到安全软件报警提示木马病毒的情况,不要冒险添加信任运行,就可以拦截此类木马攻击。
IOCs:
d61c2b9ca4a6c6ba5f367198b2e1eb30
3a9c8b204fb373c312a48fc45fa74be0
f464f26332512fc075f3c088713205e4
4056f6af5ca4431316432a1a7256cab5
0cdb721b8f700718ef7c43b33625b1a9
5fa74f6e4edb21cc8b0b0bf489972dd0
044a3fd3d33716b4640e8d5bf6f46fd3
d0013f7df57ac1d4e39d4e2f77a3df03
8da5e77c08f41f69e5e5382ef3c4f5ae
a92da0aa9cb5363feac6cb202f7119b0
3653b0e6f4c3d11234e188af20c80afe
01d1d4d61a5bb66683f45021bfcd72ab
18d8904a87ee84c7c9b08f04d9f8af78
17fa808c4f1f04a4c88b2664279cfc9e
4489d822037c3bbd94432492310b8b20
6977abb77d7c8f6c85601a1c6a00c712
8be981f8e04d0aa79c35ce15765a5352
8ba90ee5cd218a1ca26d782d4a5ffd8c
1ba4bd672225969c890f4427e49cbea5
73bcfbee8c0b8212e7adb19b6291b06a
f80bc9373815909d18e162c197f84580
22b1e536e6383674d1a83ee045b21a5a
2e15c51f067fea6bf51dbae8579e9cfa
00b1228f86e58c2cc3fb26b263f89943
12f0fdb027df0f76281ce109d8d61108
87cdb7541c7855b66e1d40aeaffef98a
9eb112c78caf78e27fffb50f62e408e8
87243fab70d97ac1a065c2ce534d38be
d230383f64a0f23fa0c54e1787df9b74
e88ae015cc0034f000fcd984a4e2c914
71bcd52e9e4ec145973d53f2296a7ad7
3b6688d5c9759cee8feb59ab6fc05d51
26dda63da6218410e5468bff15b270db
036cdc3a5ca77b56e98c6e42852cb92c
3b9521f3c28a19b52a777601228fbd89
72825c26d689e443f7b727d3b7157cb0
7da92fbb13ec0d8d23aa44c38c829c42
06a0efc721951438e62f9d55f019024c
4c411e8475382f7a5327db3e9a3b212f
bbee2798a74d15f4e76000a3e138e10c
384a63b76e77351b389b505f44a7ebe9
04c8e301410689eeedaa87e269c56c3a
08cfb0455f3ec393a9af7046db350907
ef7f82befb9d710bb71c8fdb06e4e491
2b3e2f17d9a5b1c415f48f5a0c8b21cd
f730fee773c085e236a4906625386d6c
da6067e89b809a5af14ed04aa83d88bc
35a32851b718c95248d3caaec342ee53
202652a4f2620bbb6bf03fce4bb5f4e9
12c9af6100458b2ca5ee60af2fba75d3
abf028ec738cbc2a05f71a9c8b1c7fe7
dabf3f13fc934969cec78e931ad4866c
d26a0312dbd779c9016c4617a9527c7a
ce617ac4b66c3202569c887812d2e13a
1763e21708a38ad39c1e46aa32ad1a4b
7bcb7d39187c5f5606a9960cdcfba9cd
2be42b82e1f84868933f91a98eaa0f05
5412393c13ceb643c1aef28eb9a65f07
98610a0255d313cba72902938f1b
3.【济南】2023年第一批配装眼镜产品质量市级监督抽查结果
2023年第一批重点工业产品质量市级监督抽查(二)共抽查生产领域配装眼镜产品80批次。
本次抽查依据GB 10810.1-2005 《眼镜镜片 第1部分:单光和多焦点镜片》、GB 10810.3-2006 《眼镜镜片及相关眼镜产品 第3部分:透射比规范及测量方法》、GB 13511.1-2011 《配装眼镜 第1部分:单光和多焦点》等标准的要求,对配装眼镜产品的光学中心垂直互差、可见光透射比(右侧可见光透射比,左侧可见光透射比)、光学中心单侧水平偏差(左侧光学中心单侧水平偏差,右侧光学中心单侧水平偏差)、装配质量-金属框架眼镜锁接管的间隙、太阳紫外A波段透射比(右侧太阳紫外A波段透射比,左侧太阳紫外A波段透射比)、球镜顶焦度偏差(左侧球镜顶焦度偏差,右侧球镜顶焦度偏差)、柱镜轴位偏差(左侧柱镜轴位偏差,右侧柱镜轴位偏差)、镜片色泽、镜片材料和表面质量、镜架使用的材料、太阳紫外B波段透射比(左侧太阳紫外B波段透射比,右侧太阳紫外B波段透射比)、标志、柱镜顶焦度偏差(右侧柱镜顶焦度偏差,左侧柱镜顶焦度偏差)、光学中心水平偏差等项目进行了检验。
本次抽查发现济南市历城区明亮眼镜店(被抽样的不合格生产者/销售者名称)1家生产者/销售者(根据抽样情况据实选择)的1批次产品不符合相关标准的要求,不合格项目为光学中心水平偏差、光学中心单侧水平偏差(左侧光学中心单侧水平偏差,右侧光学中心单侧水平偏差)项目。对本次抽查发现的不合格产品生产者/销售者(根据检验结果据实选择),山东省市场监督管理局已责成相关市场监督管理部门依据《中华人民共和国产品质量法》《产品质量监督抽查管理暂行办法》以及国家市场监督管理总局、山东省市场监督管理局关于监督抽查的有关规定,做好不合格结果处理工作。
2023年配装眼镜产品质量市级监督抽查不合格情况汇总表序号产品名称抽查领域企业名称统一社会信用代码标称生产单位名称生产日期/批号商标规格型号综合判定1配装眼镜生产领域济南市历城区明亮眼镜店92370128MA3LCTBU1Q济南市历城区明亮眼镜店20237.19/R:-4D L:-4.5D PD:58mm不合格 2023年配装眼镜产品质量市级监督抽查合格情况汇总表序号产品名称抽查领域企业名称统一社会信用代码标称生产单位名称生产日期/批号商标规格型号综合判定1配装眼镜生产领域济南市天桥区周氏齐鲁茂昌眼镜行91370105MA3EQ0103L济南市天桥区周氏齐鲁茂昌眼镜行2023.10.9/R:-4D-1.5D×150 L:-4.25D-1.25D×45 PD:62mm合格2配装眼镜生产领域济南市天桥区视达眼镜店91370105MA3DG03J6B济南市天桥区视达眼镜店2023.10.9/R:-4.25D-0.75D×110 L:-4.25D-1D×135 PD:59mm合格3配装眼镜生产领域济南市天桥区丽之康眼镜店91370105MA3U59TKX6济南市天桥区丽之康眼镜店2023.10.9/R:-4D-1.25D×150 L:-4.5D-0.5D×165 PD:58mm合格4配装眼镜生产领域山东忆展眼镜有限公司济南泉城路店91370102MA3MABMN5W山东忆展眼镜有限公司济南泉城路店2023.9.27/R:-4D-1.5D×150 L:-4.5D-1D×45 PD:65mm合格5配装眼镜生产领域济南立创光业商贸有限公司世茂广场店91370102MA3M00DF8L济南立创光业商贸有限公司世茂广场店2023.9.27/R:-4D-1.5D×150 L:-4.5D-1D×45 PD:65mm合格6配装眼镜生产领域济南姜玉坤视光科技有限公司王舍人分公司91370112MA3MT99H14济南姜玉坤视光科技有限公司王舍人分公司2023.8.29/R:-4.25D-1D×170 L:-4D-0.75D×15 PD:63mm合格7配装眼镜生产领域济南轻镜生活眼镜店91370100MA3MU1A7XP济南轻镜生活眼镜店2023.8.30/R:-4D-0.5D×20 L:-4D-1.25D×105 PD:60mm合格8配装眼镜生产领域济南齐鲁茂昌眼镜有限公司91370100MA3QWJQ91W济南齐鲁茂昌眼镜有限公司2023.8.29/R:-4D-1.25D×150 L:-4.25D-0.75D×45 PD:62mm合格9配装眼镜生产领域济南市章丘区东亮眼镜店91370181MA3M6JRGXQ济南市章丘区东亮眼镜店2023/8/16/R:-4.25D-1D×50 L:-4.25D-0.75D×135 PD:59mm合格10配装眼镜生产领域济南高新区新佰视眼视光中心91370100MA7D8TRE00济南高新区新佰视眼视光中心2023.8.30/R:-4.5D-0.75D×80 L:-4.5D-1D×165 PD:58mm合格11配装眼镜生产领域济南市章丘圣井鑫亮眼镜店92370181MA3NGU0P7U济南市章丘圣井鑫亮眼镜店2023/8/4/R:-4.5D-0.75D×150 L:-4D-1.25D×105 PD:60mm合格12配装眼镜生产领域济南华创眼镜有限公司91370105MA7E2C2760济南华创眼镜有限公司2023.8.31/R:-4.25D-1.25D×170 L:-4.5D-0.75D×75 PD:61mm合格13配装眼镜生产领域章丘市高官寨魏兵百亮眼镜店92370181MA3LGKC18D章丘市高官寨魏兵百亮眼镜店2023/8/10/R:-4.5D-1.25D×80 L:-4.25D-0.75D×45 PD:62mm合格14配装眼镜生产领域章丘市双山百亮眼镜店91370181MA3C7Y9P65章丘市双山百亮眼镜店2023/8/4/R:-4.25D-1.25D×110 L:-4.5D-0.5D×75 PD:61mm合格15配装眼镜生产领域章丘姜玉坤眼镜有限公司埠村分公司91370181MA3N7FG47R章丘姜玉坤眼镜有限公司埠村分公司2023/8/16/R:-4D-0.75D×150 L:-4.5D-1D×165 PD:58mm合格16配装眼镜生产领域章丘姜玉坤眼镜有限公司唐人中心分公司91370181MA3FALNX4M章丘姜玉坤眼镜有限公司唐人中心分公司2023/8/16/R:-4.25D-1.25D×170 L:-4.25D-0.5D×135 PD:59mm合格17配装眼镜生产领域章丘区视亮眼镜店92370181MA3U397564章丘区视亮眼镜店2023/8/15/R:-4.25D-0.75D×50 L:-4D-1.25D×15 PD:63mm合格18配装眼镜生产领域商河县明亮眼镜店92370126MA3LFRF37C商河县明亮眼镜店2023.8.9/R:-4.25D-1.25D×110 L:-4D-1D×15 PD:63mm合格19配装眼镜生产领域章丘姜玉坤眼镜有限公司913701817544778761章丘姜玉坤眼镜有限公司2023/8/16/R:-4.25D-0.5D×110 L:-4D-1.25D×15 PD:63mm合格20配装眼镜生产领域济南市百亮眼镜有限公司91370181MA3RUBAF7Q济南市百亮眼镜有限公司2023.8.4/R:-4.5D-1.25D×20 L:-4.5D-0.5D×165 PD:58mm合格21配装眼镜生产领域商河县视康眼镜店92370126MA3PNAT29H商河县视康眼镜店2023.8.3/R:-4D-1.25D×150 L:-4D-1D×105 PD:60mm合格22配装眼镜生产领域济南济阳区孟霞眼镜店91370125MA3P9KUW1A济南济阳区孟霞眼镜店2023.8.24/R:-4D-1.25D×80 L:-4.25D-1.25D×45 PD:62mm合格23配装眼镜生产领域济南市天桥区吴飞眼镜经营部92370105MA3DN1UP8H济南市天桥区吴飞眼镜经营部2023.8.31/R:-4D-1.25D×80 L:-4.5D-1.25D×165 PD:58mm合格24配装眼镜生产领域济南明朗眼镜有限公司91370105MA3DGCKH09济南明朗眼镜有限公司2023.8.30/R:-4.25D-0.75D×170 L:-4D-0.75D×15 PD:63mm合格25配装眼镜生产领域银座集团股份有限公司913700002671701644银座集团股份有限公司2023.8.21/R:-4D-0.75D×20 L:-4.5D-1.25D×165 PD:58mm合格26配装眼镜生产领域济南市百亮眼镜有限公司汇泉路分公司91370181MA94RAX1XJ济南市百亮眼镜有限公司汇泉路分公司2023/8/4/R:-4.25D-0.75D×50 L:-4.5D-1D×75 PD:61mm合格27配装眼镜生产领域济南泉茂宝岛眼镜有限公司济南印象城分公司91370112MA3PPJPR31济南泉茂宝岛眼镜有限公司济南印象城分公司2023.8.29/R:-4D-1.25D×150 L:-4.25D-0.5D×45 PD:62mm合格28配装眼镜生产领域济南市天桥区谢氏眼镜商行92370105MA3RQDF34H济南市天桥区谢氏眼镜商行2023.8.31/R:-4.5D-1.25D×150 L:-4.5D-1.25D×165 PD:58mm合格29配装眼镜生产领域济南市天桥区振新眼镜商行92370105MA3LEF9307济南市天桥区振新眼镜商行2023.8.31/R:-4D-0.75D×80 L:-4D-0.75D×105 PD:60mm合格30配装眼镜生产领域济南天桥区茂之昌眼镜行91370105MA949YK57C济南天桥区茂之昌眼镜行2023.8.31/R:-4D-1.25D×150 L:-4.25D-1D×45 PD:62mm合格31配装眼镜生产领域商河县新视力眼镜店92370126MA3L8XBA7K商河县新视力眼镜店2023.8.7/R:-4.5D-0.75D×150 L:-4.25D-1.25D×45 PD:62mm合格32配装眼镜生产领域天桥区兆旭眼镜店92370105MA3LC37D6J天桥区兆旭眼镜店2023.8.30/R:-4.25D-0.75D×50 L:-4D-0.75D×15 PD:63mm合格33配装眼镜生产领域济阳区旭之光眼镜店92370125MA3U3L062D济阳区旭之光眼镜店2023.8.4/R:-4D-0.5D×80 L:-4.5D-0.75D×165 PD:58mm合格34配装眼镜生产领域商河县雪亮眼镜行92370126MA3LFCDP3B商河县雪亮眼镜行2023.8.3/R:-4.25D-0.5D×170 L:-4.5D-0.75D×75 PD:61mm合格35配装眼镜生产领域济南文茂诚信眼镜有限责任公司91370105MA3RE782XG济南文茂诚信眼镜有限责任公司2023.8.30/R:-4.5D-0.5D×20 L:-4.25D-1D×45 PD:62mm合格36配装眼镜生产领域济南先锋光学眼镜有限公司91370125307259914U济南先锋光学眼镜有限公司2023.8.4/R:-4.25D-0.75D×50 L:-4.25D-1.25D×135 PD:59mm合格37配装眼镜生产领域济阳区崔寨镇硕明眼镜店92370125MA3RG0K36H济阳区崔寨镇硕明眼镜店2023.8.7/R:-4.25D-0.75D×50 L:-4.5D-0.5D×75 PD:61mm合格38配装眼镜生产领域济南利鹏眼镜经营店91370105MA94YY2WXA济南利鹏眼镜经营店2023.8.31/R:-4.5D-1D×80 L:-4D-0.75D×105 PD:60mm合格39配装眼镜生产领域济南茂昌眼镜有限公司解放东路分公司91370102069045119G济南茂昌眼镜有限公司解放东路分公司2023.8.21/R:-4.5D-1D×80 L:-4D-0.75D×105 PD:60mm合格40配装眼镜生产领域济南时代茂昌眼镜有限公司峪悦里分公司91370100MA3N146D4Q济南时代茂昌眼镜有限公司峪悦里分公司2023.8.21/R:-4.25D-1.25D×110 L:-4.25D-0.5D×135 PD:59mm合格41配装眼镜生产领域济南银座购物广场有限公司章丘分公司91370181677255822P济南银座购物广场有限公司章丘分公司2023.8.21/R:-4D-1D×80 L:-4.25D-0.75D×45 PD:62mm合格42配装眼镜生产领域山东银座商城股份有限公司洪楼分公司91370100677260314R山东银座商城股份有限公司洪楼分公司2023.8.21/R:-4D-0.5D×80 L:-4.5D-1.25D×165 PD:58mm合格43配装眼镜生产领域银座集团股份有限公司济南银座燕山购物广场91370100677261966E银座集团股份有限公司济南银座燕山购物广场2023.8.21/R:-4.25D-0.75D×110 L:-4.5D-1.25D×75 PD:61mm合格44配装眼镜生产领域华信时代茂昌(济南历城区)眼镜销售有限公司91370112MA7JYKEKXH华信时代茂昌(济南历城区)眼镜销售有限公司2023.8.21/R:-4.5D-0.75D×150 L:-4.5D-1.25D×165 PD:58mm合格45配装眼镜生产领域山东忆展眼镜有限公司济南槐荫南辛庄店91370104MA3PR63E27山东忆展眼镜有限公司济南槐荫南辛庄店2023.8.21/R:-4.5D-1.5D×150 L:-4.25D-0.75D×45 PD:62mm合格46配装眼镜生产领域济南傲雷眼镜有限公司91370105MA3F8FJ1XR济南傲雷眼镜有限公司2023.8.31/R:-4.25D-1.25D×50 L:-4.5D-1.25D×75 PD:61mm合格47配装眼镜生产领域济南市天桥区春明大明眼镜店91370105MA3NT25T62济南市天桥区春明大明眼镜店2023.8.30/R:-4.5D-1.25D×150 L:-4D-0.5D×105 PD:60mm合格48配装眼镜生产领域济南金钢眼镜视光有限公司91370125MA94GA5X3X济南金钢眼镜视光有限公司2023.8.2/R:-4.5D-1.25D×20 L:-4D-1D×105 PD:60mm合格49配装眼镜生产领域济南市天桥区月明眼镜商行92370105MA3RX8G78A济南市天桥区月明眼镜商行2023.8.1/R:-4.25D-0.75D×110 L:-4D-1D×15 PD:63mm合格50配装眼镜生产领域济南市天桥区海通眼镜商行92370105MA3LGEUD4C济南市天桥区海通眼镜商行2023.8.31/R:-4.25D-0.5D×110 L:-4.5D-1.25D×75 PD:61mm合格51配装眼镜生产领域济南百亮眼镜店91370105MA94F9PH1K济南百亮眼镜店2023.8.31/R:-4.25D-0.5D×110 L:-4.25D-1D×135 PD:59mm合格52配装眼镜生产领域银座集团济南长清购物广场有限公司913701133072362961银座集团济南长清购物广场有限公司2023.8.21/R:-4D-0.75D×20 L:-4.25D-1.25D×45 PD:62mm合格53配装眼镜生产领域银座集团股份有限公司济南银座华信购物广场91370112664852345X银座集团股份有限公司济南银座华信购物广场2023.8.21/R:-4D-1D×80 L:-4D-0.75D×105 PD:60mm合格54配装眼镜生产领域济南立创光业商贸有限公司万虹广场店91370112MA3NEQGM25济南立创光业商贸有限公司万虹广场店2023.8.21/R:-4.25D-1D×50 L:-4D-0.75D×15 PD:63mm合格55配装眼镜生产领域山东忆展眼镜有限公司龙湖奥体天街店91370102MA3U9H6DXU山东忆展眼镜有限公司龙湖奥体天街店2023.8.21/R:-4.25D-1.25D×50 L:-4.25D-0.5D×135 PD:59mm合格56配装眼镜生产领域济南银座商城有限责任公司七里山分公司913701006898313562济南银座商城有限责任公司七里山分公司2023.8.21/R:-4.5D-0.5D×150 L:-4D-1.25D×105 PD:60mm合格57配装眼镜生产领域银座集团股份有限公司济南银座高新区购物广场91370100568144824T银座集团股份有限公司济南银座高新区购物广场2023.8.21/R:-4.25D-1.25D×50 L:-4.25D-0.75D×135 PD:59mm合格58配装眼镜生产领域济南立创光业商贸有限公司高新万达店91370100MA3PLDPX4G济南立创光业商贸有限公司高新万达店2023.8.21/R:-4.25D-0.5D×110 L:-4D-1.25D×15 PD:63mm合格59配装眼镜生产领域山东忆展眼镜有限公司济南万虹广场店91370112MA3NF2AD0D山东忆展眼镜有限公司济南万虹广场店2023.8.21/R:-4.5D-1.25D×20 L:-4.25D-0.5D×45 PD:62mm合格60配装眼镜生产领域市中区英雄山亨得利眼镜店91370103MA3RAGJU1H市中区英雄山亨得利眼镜店2023.8.18/R:-4.25D-1.25D×110 L:-4.25D-0.75D×135 PD:59mm合格61配装眼镜生产领域济南博睿特眼视光有限公司91370104MA94J6B07K济南博睿特眼视光有限公司2023.7.25/R:-4D-0.75D×80 L:-4D-1.25D×105 PD:60mm合格62配装眼镜生产领域济南市长清区精之功眼镜店91370113MA3NA35F02济南市长清区精之功眼镜店2023.8.1/R:-4.5D-0.5D×80 L:-4D-1.25D×105 PD:60mm合格63配装眼镜生产领域平阴县美玲精益眼镜超市彩虹分店91370124MACBK44K8F平阴县美玲精益眼镜超市彩虹分店2023.7.20/R:-4.5D-0.5D×80 L:-4.5D-0.75D×165 PD:58mm合格64配装眼镜生产领域平阴县荣茂眼镜店92370124MAC9A4F167平阴县荣茂眼镜店2023.7.21/R:-4.25D-1.25D×50 L:-4D-1D×15 PD:63mm合格65配装眼镜生产领域平阴科睿尔视光配镜有限公司91370124MA3MG65AX6平阴科睿尔视光配镜有限公司2023.7.24/R:-4.25D-0.75D×110 L:-4.25D-1.25D×135 PD:59mm合格66配装眼镜生产领域济南孔氏精益眼镜店91370103MA3RDQ2Q4X济南孔氏精益眼镜店2023.7.21/R:-4.25D-0.75D×170 L:-4.5D-1D×75 PD:61mm合格67配装眼镜生产领域济南姜玉坤眼镜有限公司长清分公司91370113MA3CGY7912济南姜玉坤眼镜有限公司长清分公司2023.8.2/R:-4.25D-1.25D×50 L:-4.5D-0.75D×75 PD:61mm合格68配装眼镜生产领域济南槐荫金香蕉眼镜店92370104MA9441FP1U济南槐荫金香蕉眼镜店2023.7.25/R:-4.25D-1.25D×110 L:-4.5D-0.5D×75 PD:61mm合格69配装眼镜生产领域济南市昌明眼镜有限公司91371203673179949Q济南市昌明眼镜有限公司2023.8.14/R:-4D-1D×150 L:-4D-0.5D×105 PD:60mm合格70配装眼镜生产领域济南市莱芜精益眼镜有限公司91371202L07852620L济南市莱芜精益眼镜有限公司2023.8.10/R:-4.25D-1D×110 L:-4D-0.5D×15 PD:63mm合格71配装眼镜生产领域济南市钢城区视康眼镜店92371203MA3FJ56T98济南市钢城区视康眼镜店2023.8.9/R:-4.5D-1.25D×80 L:-4.25D-1.25D×45 PD:62mm合格72配装眼镜生产领域济南槐荫依视佳眼镜店92370104MA3U5Y3841济南槐荫依视佳眼镜店2023.7.24/R:-4.25D-0.75D×170 L:-4D-1.25D×15 PD:63mm合格73配装眼镜生产领域济南德润生物科技有限公司91370104MA94W0EJ66济南德润生物科技有限公司2023.7.24/R:-4.25D-1D×110 L:-4.25D-0.75D×135 PD:59mm合格74配装眼镜生产领域南山区靓铭眼镜店92370128MA3Q53R383南山区靓铭眼镜店2023.7.18/R:-4.25D-1D×50 L:-4D-0.5D×15 PD:63mm合格75配装眼镜生产领域济南新润光眼镜有限公司91370128MA3Q69JD03济南新润光眼镜有限公司2023.7.18/R:-4.25D-0.75D×50 L:-4.5D-1.25D×75 PD:61mm合格76配装眼镜生产领域济南市历城区西营精功眼镜店92370128MA3LCLRA81济南市历城区西营精功眼镜店20230718/R:-4D-0.75D×150 L:-4.5D-1D×165 PD:58mm合格77配装眼镜生产领域济南市钢城区光明眼镜有限公司91370117MA3RMJTDX4济南市钢城区光明眼镜有限公司2023.8.9/R:-4.25D-0.75D×110 L:-4.5D-0.75D×75 PD:61mm合格78配装眼镜生产领域济南市莱芜区新视觉眼镜行91370116MA3PMNBR9N济南市莱芜区新视觉眼镜行2023.8.11/R:-4.25D-1.25D×170 L:-4.25D-1.25D×135 PD:59mm合格79配装眼镜生产领域济南市莱芜区王旭芳眼镜店92371202MA3FJ4E93U济南市莱芜区王旭芳眼镜店2023.8.16/R:-4.5D-0.75D×150 L:-4.5D-0.75D×165 PD:58mm合格 2023年配装眼镜产品质量市级监督抽查未抽到企业名单序号企业名称抽查状态1济南市天桥区尼桑眼镜商行不生产本次抽样产品,只批发零售。
现场核查情况属实。2济南槐荫镜伟眼镜销售中心通过登记的住所或者经营场所无法联系。
现场核查情况属实。3济南市天桥区林穆眼镜商行店面拆除。
现场核查,情况属实,查找不到商家本人。
4.灯具质量抽检结果大曝光 看看你家灯具合标准吗
2019年10月11日,深圳市市场监督管理局发布关于2019年深圳市灯及灯具产品质量监督抽查结果的通报。本次共抽查了40家企业生产销售的74批次产品,检验发现不合格样品29批次,不合格产品发现率为39.2%。
据通报,2019年第一季度,深圳市市场监管局组织开展了灯及灯具产品质量监督抽查。本次监督抽查,依据《灯具第1部分:一般要求与试验》(GB7000.1-2015)、《灯具第2-1部分:特殊要求固定式通用灯具》(GB7000.201-2008)、等标准的要求,对灯及灯具产品的标记/标志、结构、互换性、意外接触带电部件的防护、潮湿处理后的绝缘电阻和介电强度、机械强度等强制性项目进行了检测。
从领域分布来看,此次抽查生产领域10家受检单位10批次产品,未发现不合格产品;抽查流通领域实体店22家受检单位54批次产品,发现不合格产品23批次,不合格产品发现率为42.6%;抽查流通领域互联网购物平台(天猫商城)8家受检单位10批次产品,发现不合格产品6批次,不合格产品发现率为60%。
此次抽查发现的不合格项目主要有:耐热、耐火和耐起痕、标记/标志、结构、外部接线和内部接线、互换性、接地规定、绝缘电阻和电气强度/介电强度、爬电距离和电气间隙、防触电保护、机械强度、谐波电流。
针对抽查中发现的产品质量问题,深圳市市场监督管理局已经依据相关法律法规的规定对不合格产品生产企业、经营单位予以处理。
在此,深圳市市场监督管理局提醒生产者必须严格按照法律法规、国家标准组织生产,不得生产销售不合格产品;生产者发现其生产的灯及灯具产品存在安全隐患、缺陷,可能对人体健康和人身、财产安全造成损害的,应当启动缺陷调查、主动召回产品。
销售者必须严格履行进货检查验收制度,查验供货商的经营资格,验明产品合格证明和产品标识,采取措施保证产品质量,不得销售不合格产品,对公告的不合格产品必须立即停止销售。消费者要求退货的,应当负责退货。
消费者在选购或使用灯及灯具产品时,应注意以下几点:
尽量选购知名企业生产的产品,一般而言这类知名度高、信誉强的企业无论是安全项目还是性能项目都可以达到国家规定的标准。
选购时应做到“三看”
一看产品标识是否齐全,正规产品的标识往往比较规范,应标识如下内容:商标和厂名、产品型号规格、额定电压、额定频率、额定功率。
二看灯具是否有CCC安全认证标志。
三看灯具带电体是否外露,光源装入灯座后,手指应不能触及带电的金属灯头。
在挑选自镇流荧光灯和LED灯时,首先需注意拿灯的部位,应拿塑料件部位,不应直接用手去握灯管部位。其次检查灯的外观,灯具的塑料件部位应清晰地标注产品的相关信息如商标、厂名厂址、额定电压和电压范围、额定功率、额定频率等;灯管的玻壳应光洁,无气泡,灯管内的荧光粉涂层应细腻,无颗粒,呈均匀白色;灯头与灯管应呈垂直状态,不应有倾斜;灯头的焊锡台应较平整,灯头两端引线的焊锡不应太高;灯管与塑料件之间应牢固连接,用力拧灯头和灯体的连接部位,不应松动;用手摇晃整灯不应有响动。
使用过程中,注意观察灯管在通电后,发光是否正常均匀。同时,灯管应无明显黑斑,发光体无闪烁现象。
节能灯和LED灯在正常工作状态下,不应过烫,否则会影响使用寿命。同时,节能灯点亮时,灯管两端发黑,灯丝发红或闪亮,都说明该节能灯存在不同程度的质量问题。
2019年深圳市灯及灯具产品质量监督抽查发现不合格项目产品及企业名单
序号
受检单位名称
样品名称
标称商标
型号规格等级
生产日期
(标称)生产单位名称
报告结论
不合格项目
备注
1
深圳市龙岗区普宜捷灯饰经销部
LED投光灯
卡焰
LED中国星投光灯
2018.11
中山市一声喊照明灯具有限公司(监制)
不合格
1、防尘、防固体异物与防水;2、标记;3、结构;4、爬电与电气间隙;5、接地;6、外部接线与内部接线;7、绝缘电阻与电气强度;8、谐波电流
/
2
深圳市坪山新区伟发五金交电商行
LED平板灯
贝恩斯
300*300 AC220V 50Hz
2018.Ⅳ
九江市精彩无限光电科技有限公司
不合格
1、标记;2、结构;3、外部接线和内部接线;4、防触电保护;5、绝缘电阻和电气强度;6、爬电距离与电气间隙;7、耐热、耐火和耐起痕
/
3
深圳市南山区乐安居市场新顶鑫灯饰店
嵌入式通用灯具
奔豪
SZX202-7W
2018.08.
广东三志照明有限公司
不合格
1、标记;2、结构;3、爬电距离和电气间隙;4、外部接线和内部接线;5、防触电保护;6、绝缘电阻和电气强度
/
4
深圳市优登灯饰有限公司(网店名:天猫/北纬日光旗舰店)
可移式白炽灯具
北纬日光
89007
/
深圳市优登灯饰有限公司
不合格
1、标记;2、结构;3、爬电距离和电气间隙;4、外部接线和内部接线;5、防触电保护;6、耐热、耐火和耐起痕
https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-14755260899.162.488677b2O2c2Du&id=589110573547&rn=6384760821e6f81da805bd8b02b0716a&abbucket=6
5
深圳市龙岗区普宜捷灯饰经销部
LED投光灯
卡焰
LED投光灯 195×45×165mm
2019-3
中山市一声喊照明灯具有限公司(监制)
不合格
1、标记;2、结构;3、外部接线和内部接线;4、谐波电流;5、接地规定
/
6
深圳市木灯世界灯饰有限公司(网店名:天猫/宇磊灯饰旗舰店)
可移式通用灯具
宇磊灯饰
MT018B
/
中山市云风源照明电器厂
不合格
1、标记;2、结构;3、爬电距离和电气间隙;4、外部接线和内部接线;5、防触电保护
https://detail.tmall.com/item.htm?spm=a1z10.3-b.w4011-14772863019.65.21461908fVsZPr&id=542011303191&rn=c8149d25c6b5df44670c3c47a319ebcc&abbucket=6&skuId=3458396175171
7
深圳市坪山新区泰丰五金装饰部
嵌入式灯具
辉帅
HS-LSMD-9
2018-12
佛山市新辉帅照明电器有限公司
不合格
1、标记;2、外部线和内部接线;3、电气强度;4、耐热,耐火和耐起痕
/
8
深圳市坪山新区泰丰五金装饰部
嵌入式灯具
辉帅
HS-LSMD-18
2018-12
佛山市新辉帅照明电器有限公司
不合格
1、标记;2、外部接线和内部接线;3、电气强度;4、耐热,耐火和耐起痕
/
9
深圳市人人乐商业有限公司天悦南湾超市
LED小夜灯
柯丽雅
L-401
2017-9-30
汕头市柯丽雅电子科技有限公司
不合格
1、标记;2、耐热、耐火和耐起痕;3、结构
/
10
深圳市人人乐商业有限公司天悦南湾超市
LED小夜灯
柯丽雅
L-408
#########
汕头市柯丽雅电子科技有限公司
不合格
1、标记;2、耐热、耐火和耐起痕;3、结构
/
11
深圳市人人乐商业有限公司天悦南湾超市
炫彩小夜灯
/
8305
/
广州市华升塑料制品有限公司
不合格
1、标记;2、结构;3、耐热、耐火和耐起痕
/
12
深圳市龙井华城百货有限公司
小夜灯
家之伴
JZ-YD013
/
深圳市科冠电器有限公司
不合格
1、标记;2、结构;3、耐热、耐火和耐起痕
/
13
深圳市南山区乐安居市场新顶鑫灯饰店
嵌入式LED灯具
/
FP220-B
2018-12-8
广东佛普照明有限公司
不合格
1、标记;2、内部和外部接线;3、绝缘电阻和电气强度
/
14
深圳市百佳华百货有限公司松岗店
炫彩小夜灯
/
8307 220V~50Hz 0.1W 合格品
2018-9-5
广州市华升塑料制品有限公司
不合格
1、标记;2、结构;3、耐热、耐火和耐起痕
/
15
深圳百安居装饰建材有限公司泰然店
LED筒灯SUN
三雄·极光
PAK560230 220V~50Hz 4W
2016-2
广东三雄极光照明股份有限公司
不合格
1、标记;2、耐热、耐火和耐起痕
/
16
华润万家有限公司松岗东方店
LED小夜灯
/
DP-430 220V~50/60Hz 0.6W/0.02A 1×0.5W 合格品
2019-2-1
广东久量股份有限公司
不合格
1、标记;2、耐热、耐火和耐起痕
/
17
深圳市百佳华百货有限公司松岗店
青花瓷小夜灯
/
8304 220V~50Hz 3×0.1W 合格品
2018-9-5
广州市华升塑料制品有限公司
不合格
1、标记;2、耐热、耐火和耐起痕
/
18
华润万家有限公司松岗东方店
LED光控小夜灯
图形商标
KM-5215 220V~50Hz 22mA 0.5W 合格品
/
长方集团康铭盛(深圳)科技有限公司
不合格
1、结构;2、耐热、耐火和耐起痕
/
19
深圳市爱耐特宝科技有限公司(网店名:天猫/爱耐特旗舰店)
遥控小夜灯
爱耐特
SY-YKXYD4
/
东莞市锦星电子科技有限公司
不合格
1、标记;2、结构
/
20
深圳市坪山新区伟发五金交电商行
志亮防频闪LED灯
/
ZL002012W 12W A80
2017-6
深圳市志亮照明电器有限公司
不合格
1、标志;2、互换性
/
21
深圳市蚁点科技有限公司(网点名:天猫/蚁点旗舰店)
LED台灯
/
TA-01
/
深圳市闪点照明科技有限公司
不合格
1、标记;2、耐热、耐火和耐起痕
https://detail.tmall.com/item.htm?spm=a1z10.5-b-s.w4011-18738576757.52.2d967512w90LQa&id=574273581921&rn=d9bae79b743dab80f43e6c317ccc57f4&abbucket=7&skuId=4010195777886
22
深圳市同健光电有限公司(网店名:天猫/好视力灯具旗舰店)
LED台灯
/
TG028
2019-4
深圳市圣宏亮科技有限公司
不合格
耐热、耐火和耐起痕
https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.172.305994b9rGkMw6&id=585969200987&skuId=4187089546446&areaId=440300&user_id=279750418&cat_id=2&is_b=1&rn=cfd0b87dd1a53751cfc5e72494f6517e
23
深圳市同健光电有限公司(网店名:天猫/好视力灯具旗舰店)
好视力LED夹子灯
好视力
TG902
2017-11
中山市相红电器有限公司
不合格
耐热、耐火和耐起痕
https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-14440157868.23.538b7351JEocQX&id=520843539983&rn=259bd8218bc55d3e1d4b49054f4e6a4b&skuId=3692215718948
24
华润万家有限公司松岗东方店
LED光控小夜灯
图形商标
KM-5212 220V~50Hz 22mA 0.5W 合格品
/
深圳市康铭盛科技实业股份有限公司
不合格
耐热、耐火和耐起痕
/
25
深圳市龙岗区普宜捷灯饰经销部
LED球泡
卓睿
正白ZR-QP03
2018-11
中山市一声喊照明灯具有限公司(监制)
不合格
标志
/
26
深圳市坪山新区伟发五金交电商行
志亮防频闪LED灯
/
ZL002005W 5W A55
2017-3-26
深圳市志亮照明电器有限公司
不合格
互换性
/
27
深圳市光影灯饰有限公司
LED 柱形泡
/
BPZ1530-865-E27 18W 6500K 220V~50Hz
/
深圳市兆驰照明股份有限公司
不合格
潮湿处理后的绝缘电阻和介电强度
/
28
深圳市龙华区龙华金鸿五金店
FD-LED-A60-E27-7W 晨阳
飞雕
FD-LED-BPZ7A
2018-5
广东同昭光电科技有限公司
不合格
互换性
/
29
深圳市光明新区公明家顺业灯饰五金商场
LED球泡灯
图形商标
20W 220V-50Hz 6000K
/
中山市豪旺照明电器厂
不合格
机械强度
/
2019年深圳市灯及灯具产品质量监督抽查未发现不合格项目产品及企业名单
序号
受检单位名称
样品名称
标称商标
型号规格
生产日期
(标称)生产单位名称
报告结论
备注
1
茂硕电源科技股份有限公司
LED控制装置(恒流模式 可调,内置防雷管)
MOSO
LDP-105R062
/
茂硕电源科技股份有限公司
未发现不合格项目
/
2
深圳市健森科技有限公司
LED控制装置(恒流输出)
/
JSW-LAF-(H100)
2019-4-13
深圳市健森科技有限公司
未发现不合格项目
/
3
深圳市精日昌电子科技有限公司
LED控制装置
/
JT-N05100
2019-4-12
深圳市精日昌电子科技有限公司
未发现不合格项目
/
4
深圳市光大照明科技有限公司灯具制造厂
固定式灯具
/
EBF209-L60
2018-6-4
深圳市光大照明科技有限公司灯具制造厂
未发现不合格项目
/
5
深圳市洲明科技股份有限公司
LED路灯
Unilumin 洲明
UNI-STO5-1
2019-4-4
深圳市洲明科技股份有限公司
未发现不合格项目
/
6
深圳市缔轩科技有限公司
可移式灯具
/
MT-HY03T-50
2019-4-5
深圳市缔轩科技有限公司
未发现不合格项目
/
7
深圳市航嘉驰源电气股份有限公司
LED控制装置
Hontkey
HKL34P26A3-T100
2019-3-27
深圳市航嘉驰源电气股份有限公司
未发现不合格项目
/
8
深圳市好时达电器有限公司
可移式LED台灯
/
HSD9016A
2019-2-25
深圳市好时达电器有限公司
未发现不合格项目
/
9
深圳市卓明光电有限公司
LED投光灯
/
ZM-FL-P108-CW
2018-12-1
深圳市卓明光电有限公司
未发现不合格项目
/
10
深圳市火牛科技有限公司
LED控制装置
图形商标
HNHL 120100WC
2018-11-7
深圳市火牛科技有限公司
未发现不合格项目
/
11
深圳市顺电连锁股份有限公司中心城分店
LED球泡
/
LED-BPZ220/9-E27-04
2018-12-29
欧普照明电器(中山)有限公司
未发现不合格项目
/
12
深圳市顺电连锁股份有限公司中心城分店
LED球泡
/
LED-BPZ220/8-E27-3(色调30)
2018-5-2
欧普照明电器(中山)有限公司
未发现不合格项目
/
13
深圳市顺电连锁股份有限公司中心城分店
LED球泡
/
LED-BPZ220/3-E14-7(色调65)
2018-4-11
欧普照明电器(中山)有限公司
未发现不合格项目
/
14
深圳百安居装饰建材有限公司泰然店
LED吸顶灯
/
GPX1250931-22-01-C 220-240V~50/60Hz 9W
2017-11-27
厦门光莆电子股份有限公司
未发现不合格项目
/
15
深圳市福田区乐安居新洲市场鑫富迪灯饰商行
固定式灯具
Panasonic
HH-LA0607CB 220V~50Hz
2018-1-30
松下电气机器(北京)有限公司
未发现不合格项目
/
16
深圳市福田区乐安居新洲市场鑫富迪灯饰商行
固定式灯具
Panasonic
HH-LA1035CC
2018-12-3
松下电气机器(北京)有限公司
未发现不合格项目
/
17
深圳百安居装饰建材有限公司泰然店
LED吸顶灯
GOPRO
GPX2221231-19-01-C 220V~50Hz 0.12A 12W
2018-1-29
厦门光莆电子股份有限公司
未发现不合格项目
/
18
深圳市福田区乐安居新洲市场华艺灯饰店
吸顶灯
/
31808 220-240V ~50/60Hz
2017-4-1
飞利浦照明(中国)投资有限公司
未发现不合格项目
/
19
深圳市顺电连锁股份有限公司
面光源阅读台灯(孩视宝LED台灯)
/
VL132
2018-3-6
永胜(东莞)电子有限公司
未发现不合格项目
/
20
深圳市顺电连锁股份有限公司
台夹两用充电灯(孩视宝LED台灯)
/
VL017
2018-10-8
永胜(东莞)电子有限公司
未发现不合格项目
/
21
深圳市顺电连锁股份有限公司
小夜灯
/
NLTD-C2A
/
嘉兴罗尔思贸易有限公司
未发现不合格项目
/
22
深圳市福田区乐安居新洲市场鑫富迪灯饰商行
固定式灯具
Panasonic
HH-LA0606CB 220V 50Hz
2016-6-17
松下电气机器(北京)有限公司
未发现不合格项目
/
23
深圳市福田区乐安居新洲市场华艺灯饰店
飞利浦LED吸顶灯
/
33361 220-240V ~50/60Hz
2018-4-8
飞利浦照明(中国)投资有限公司
未发现不合格项目
/
24
深圳市健之家实业发展有限公司(网店名:天猫/孩视宝旗舰店)
孩视宝舒目台灯
/
VR286
2018-12-6
永胜(东莞)电子有限公司
未发现不合格项目
https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-18362176120.83.3a7f7b8eXLWZSc&id=9402263465&rn=61a878f234f5a45e4dfea4dc60b72bc9&abbucket=7&skuId=14952370343
25
深圳市罗湖天和灯饰商店
嵌入式天花射灯(星晨)
三雄极光PаK
PAK565212 合格
2018-5-4
广东三雄极光照明股份有限公司
未发现不合格项目
/
26
深圳市光之辉照明电子科技有限公司
LED嵌入式灯具
PHILIPS
80083 合格
/
飞利浦照明(中国)投资有限公司
未发现不合格项目
/
27
深圳市罗湖天和灯饰商店
筒灯
飞利浦
DN020B LED12/16W D150 合格
2019-1-28
昕诺飞(中国)投资有限公司
未发现不合格项目
/
28
深圳宜家家居有限公司
固定式LED灯具
图形商标
V1310 STAN合格
2018-9
宜家(中国)投资有限公司
未发现不合格项目
/
29
深圳市南山区乐安居市场新顶鑫灯饰店
LED筒灯
雷士照明
NLED9153
2019-10-18
重庆雷士照明有限公司
未发现不合格项目
/
30
深圳宜家家居有限公司
小夜灯
图形商标
M1611 MRKRDD 合格
2019-2
宜家(中国)投资有限公司
未发现不合格项目
/
31
深圳宜家家居有限公司
LED小夜灯
图形商标
V1202F LONGITUD 合格
2018-1
宜家(中国)投资有限公司
未发现不合格项目
/
32
深圳市龙井华城百货有限公司
自镇流荧光灯
/
YPZ220V 12W 50Hz/S-RR-N
2018-12
飞利浦照明(中国)投资有限公司
未发现不合格项目
/
33
深圳市南山区丽达五金店
T4电子节能灯
/
YPZ220/5-2U-RR
2018-Ⅲ
佛山电器照明股份有限公司
未发现不合格项目
/
34
深圳市南山区鑫富达灯饰商行
LED球泡灯
开尔
BPZ420-840 E27
2018-6
浙江旭光电子科技股份有限公司
未发现不合格项目
/
35
深圳市龙井华城百货有限公司
LED球泡
秋田
OHLEDQ70-8C
2016
佛山市顺德区欧和照明电器有限公司
未发现不合格项目
/
36
深圳市同健光电有限公司(网店名:天猫/好视力灯具旗舰店)
落地灯
/
TG610-S
2018-3
中山市相红电器有限公司
未发现不合格项目
https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-14440157868.132.498a73510Ja24b&id=38756668513&rn=3673de56f2a1b2c748125e6a262e4f03&abbucket=6
37
深圳市新视界照明科技有限公司(网店名:天猫/优显旗舰店)
视觉作业台灯
优显
AL04-02
/
深圳市新视界照明科技有限公司
未发现不合格项目
https://detail.tmall.com/item.htm?id=41974227244&ali_refid=a3_430583_1006:1110237006:N:D6VyMPMw0t8jUBz5lRwEXQ==:ba74e478c3e029f8d28ba76621c393bc&ali_trackid=1_ba74e478c3e029f8d28ba76621c393bc&spm=a230r.1.14.1&skuId=3427900515935
38
深圳市鑫坪洲百货商场
公牛爱眼LED灯
/
MQ-A107
2018-12-9
宁波公牛光电科技有限公司
未发现不合格项目
/
39
深圳市鑫坪洲百货商场
公牛爱眼LED灯
/
MQ-A10911
2019-3-6
宁波公牛光电科技有限公司
未发现不合格项目
/
40
深圳市康视佳网络科技发展有限公司(网店名:天猫/爱德华医生旗舰店)
可移动式LED灯具(II类,IP20)
/
LTS-980-01-61-B
2019-1
永曜电机(深圳)有限公司
未发现不合格项目
https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-16498323151.51.1c439775iO4qJR&id=35258304402&rn=8a48e8cee8c15022e7ef1fb6611a0577&abbucket=6&skuId=86086908576
41
深圳市龙华区龙华金鸿五金店
公牛爱眼LED灯
/
16W MQ-A11631 1500lm 220V~/50Hz 6500K
2018-3-20
宁波公牛光电科技有限公司
未发现不合格项目
/
42
深圳市光影灯饰有限公司
LED 灯泡超炫
/
A60-7-**/223 220V~50Hz E27 7W
/
佛山电器照明股份有限公司
未发现不合格项目
/
43
深圳市龙华区龙华金鸿五金店
FD-LED-A70-E27-12W 晨阳
飞雕
FD-LED-BPZ12A
2018-6
广东同昭光电科技有限公司
未发现不合格项目
/
44
深圳市光明新区公明家顺业灯饰五金商场
LED球泡灯
图形商标
6W 220V-50Hz 6500K
2019-1
佛山市顺德区勒流新国电器厂
未发现不合格项目
/
45
深圳市光明新区公明家顺业灯饰五金商场
LED球泡灯
图形商标
6W 220-50Hz 6000K
/
中山市豪旺照明电器厂
未发现不合格项目
/