runtime 很吊很强大 [转]
我们在学iOS开发中,一直使用了OC语言做面向对象开发(就是找不到对象的时候new一个就好的那种).
也许你没有研究过,你写的代码编译后到底变成了什么东西.你可以进入iOS虚拟机的目录下,查看你的app目录,你会发现一个unix的可执行文件,没错,你写的代码都在这文件中,不管你创建了多少个.h和.m文件,最终只有它一个
你肯定很像打开它,然而没有一个程序可以打开它,因为他已经不是OC文件了.
它现在保存着一个app被加载到内存时候做的事情,包括对屏幕上的UI控件的触摸响应,它使用的语言叫做汇编,一个最接近计算机硬件的语言,也就是CPU唯一能认识的计算机语言.
Runtime藏匿与 C 与 OC 之间
在接下来的说明中,我必须要提起别的事情。
我们在学 iOS 开发中,一直使用了 OC 语言做面向对象开发(就是找不到对象的时候new一个就好的那种)。
也许你没有研究过,你写的代码编译后到底变成了什么东西。你可以进入 iOS 虚拟机的目录下,查看你的 app 目录。你会发现一个 Unix 的可执行文件。没错,你写的所有代码都在这文件中,不管你创建了多少个 .h 和 .m 文件,最终只有它一个。
你肯定很想打开它,然而没有一个程序可以打开它。因为它已经不再是 Objective-C 文件了。
它现在保存着一个 app 被加载到内存时候要做的事情,包括对屏幕上的 UI 控件的触摸响应。它使用的语言叫做汇编,一个最接触计算机硬件的语言,也就是 CPU 唯一能认识的计算机语言。
如果你真的很想知道他是什么,你可以去学习汇编语言,传说中用1和0就能就能变成,到时候你就和一反向编译任何app了.
既然你知道最终变成汇编,那你一定疑问为什么会这样?
因为CPU只认得数字,不认得字母,所以这个背景下任何一个可执行的语言最终编译后都会变成汇编
然而OC到汇编并不是一步的,其中还经历了C,甚至还有可能是C++.
但是C语言是最接近汇编语言的,因为C语言有直接的内存操作.而C语言又是用英语写的,人易看懂的语言.OC在变成汇编前,它先变成了C,然后才是汇编.
你一定会问:他们变来变去跟我有毛关系!
那你一定没有发现一个问题,OC是一个面向对象的语言,C语言是面向过程的,OC和C最大的区别是C没有”类”.那么,OC变成C语言后,面向对象特有的类变成了什么,类是怎么存在面向过程语言中的?
这个问题便引出了Runtime的表现形式.
Runtime用结构体做出了类在面向过程语言的实现
“你逗我?类有属性,有方法,有实例变量,结构体顶多存实例变量,方法又是什么鬼?”
并没有逗你,只是这个结构体的确可以保存这么多东西!
那么这个接头体到底长什么样,写不同而类,变成结构体都不一样吗?
#import <objc/rutime.h>
然后进入Rutime的头文件定义,你会发现如下结构体
struct objc_class{Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__Class super_class OBJC2_UNAVAILABLE;const char *name OBJC2_UNAVAILABLE;long version OBJC2_UNAVAILABLE;long info OBJC2_UNAVAILABLE;long instance_size OBJC2_UNAVAILABLE;struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;struct objc_method_list **methodLists OBJC2_UNAVAILABLE;struct objc_cache *cache OBJC2_UNAVAILABLE;struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif} OBJC2_UNAVAILABLE;
这个结构体的名称叫做objc_class
,我相信你在开发中绝对不会用到这个结构体,你有可能看过这篇文章的时候才第一次见到,但是有个东西你可能用过,他叫Class
在 main.m 文件中在导入一个文件:
#import <objc/objc.h>
也点进去看看,会有这么几行
typedef struct objc_class*Classstruct objc_object{Class isa OBJC_ISA_AVAILABILITY;
};typedef struct objc_object*id;
我删除了中间的注释,为的是让你看的更清楚一些.
如果你有C语言基础,你一定知道typedef
的语法及含义.
苹果重新定义objc_class
这个结构体,并取名为*Class
,也就是说Class
是一个objc_class
的一个指针,同样id
也是objc_object
的一个指针.
非常的显然了,平时我们这样编写代码:
id obj=[[NSObject alloc]init];
obj
是一个NSObject
的一个对象,而本质上obj
是一个id
,而id
又是一个objc_object
结构体的一个指针,所以你其实得到的只是一个结构体指针而已
那么同样,类其实也是有对象的,因为你可以这样打:
Class c=[obj class];
这样c就是objc的类型了,然后你可以直接通过这个c来创建对象:
id other_obj=[[c alloc]init];
如果你细心的话,你会发现
Class
保存的一个类对象,但本质是objc_class
的指针
id
保存一个对象,但本质是objc_object
的指针
而我们所做的所有面向对象编程,对对象的操作,最终都会落实到结构体上,这些结构体保存着一个对象的所有信息
我们从结构体开始介绍(objc_object)
当我们获取到一个对象的时候,说白了就是一个对象的引用,也就是一个id
.上面那个结构体被重定义为*id
,那么id
就是一个objc_object
的指针.
这个结构体里有一个成员,是类型为Class
的一个isa
.我们可以这么理解,我们实例化出来的对象,他实际上只保存一个类的结构体
的指针,也就是为了说明这个对象是由什么类型实例化出来的.
现在来看看累的结构体(objc_object).
对象被实例化出来后,也就保存了那个创造自己的了的信息,这个信息也就是一个objc_class
结构体,那么我们来看看,这个结构体到底保存了哪些关于一个类的信息.
Class isa
*保存一个objc_class
的一个指针,叫做isa
*这个isa
和objc_object
中的重名,具体内容和区别之后分析Class super_class
*保存一个objc_class
的一个指针,叫做super_class
*显而易见,这里就是一个指向父类的指针,为了保存自己是从那里继承来的char *name
- 保存这个类名的字符串指针
- 这个也不用多解释,NSObject类里这里的值就是”NSObject”
long version
long info
long instance_size
- 以上三个成员不多解释,用不到
struct objc_ivar_list *ivars
- 从定义可以看出,是一个结构体指针,保存着这个类的实例变量列表
struct objc_method_list **methodLists
- 从定义可以看出,是一个结构体指针,保存着这个类的方法列表
struct objc_cache *cache
- 从定义可以看出,是一个结构体指针,保存缓存
- 什么东西可以保存到缓存,这个下文会解释
struct objc_protocol_list *protocols
- 从定义可以看出,是一个结构体指针,保存协议列表
我们写的类,实际上也就是这些东西,一个实例变量,一些方法,实现一些协议,海哥类取了个名字,拥有弗雷德所有特性.
现在我们终于知道我们写的类最终会变成了一个什么样的结构体.
你一定会问,这些结构体和我们runtime 有什么关系,它仅仅是编译时候的产物,和开发有什么关系.
机构体的作用
结构体,就是一块内存,用于统一保存大小不同且不变的集合.
在C语言中,允许我们去创建与修改结构体
对,你们有听错,就是修改.我们可以动态的修改这些结构体内的内容,甚至你再一个对象创建后,你可以真真切切地修改他的类型和父类,你甚至可以为一个类动态的增加方法,而不是在.m文件中去写方法.同样,你甚至可与修改苹果写的类.
这样很多问题变得很简单.
比如有两个人开发,你的小伙伴是主要开发者,而你就是帮他写工具类.后来我们发现,
UIAlertController
在低版本的iOS系统可能会出现闪退,但是你们的项目已经子阿哥各地方都用到了,你们觉得一个一个找到他们在做版本适配是一个大工程.此时,你就可以利用Runtime去写版本适配代码,把相关方法,都做一下修改(这写方法都是苹果写好的,你要修改就只能集成,但是Runtime不需要你继承就可以直接修改),然后导入到工程中,所有的代码均作了适配.
在你使用Runtime的时候,你必须知道Runtime是出于什么位置.
Runtime的一遍是面向过程的C语言,另一边是面向对象的OC.你通过C语言去做面向对象开发.也就是说你绕过了OC,去做了面向对象开发
OC是一个成熟的面向对象语言,他拥有一个面向对象语言应有的机制和保护,保证你写的代码在面向对象层是正确的(这里是☞你写的方法绝对不会变成另一个类的方法,而不是你写的bug).
一旦你绕过了OC,利用Runtime做面向对象开发,那么你写的代买就不受一个成熟的面向对象的语言所保护很可能出现面向对象层的运行错误.
乱用Runtime很有可能破坏面向对象机制
好吧,Runtime就是这么强大,Runtime就是这么可怕.
最终类,的结构体是可以进行数据的读写的,也就是说允许你在程序运行的时候动态的改变一个类的信息.
当程序运行到某一个时间点,我们可以给一个类添加一个方法
比如这个点事8:00,添加的方法名叫做newMethod
在,8:00前调用newMethod
会程序崩溃,蛋8:00后调用newMethod
就不会崩溃.
比如你把一个累的实例方法换到了另一个类上,然后去调用它.编译时并不会报错.但运行时就会出现错误.
你再改造OC,OC是一个成熟的语言,甚至比你还要老,你去改造他?
如果你技术成熟,改造可以让OC更能配合你的开发.
如果你技术不成熟,改造后后果无法预测.
OC的消息机制是指,在外部需要执行某个对象的方法时,使用的方式是”发送消息”而不是”调用”.
在学Runtime之前你学对不理解为什么是发送消息而不是调用.
其实很简单,最终结果都是执行一段代码.但是OC要执行那段代码是不会确定的,而”调用”是确定的.
不确定的原因
Runtime 允许我们去修改一个方法的实现,也就是说,外部告诉一个对象,执行”xxx”方法,但是那个对象是否执行和执行什么内容是不能确定的.
比如我写了一个方法
in Class MyClass:
-(void)aMethodCreatedByMyself{NSLog(@"%s","aMethodCreatedByMyself");
}
然后我在外部调用
MyClass *myObj=[MyClass alloc]init];
[myObj aMethodCreatedByMyself];
它输出了aMethodCreatedByMyself
看似确定的代码,其实是不确定的.因为你没有写任何的Runtime代码,所以这个方法没有做过任何”运行时修改”.所以你觉得它很确定.但是如果我再别的地方,对这个方法做修改,修改他的实现内容,那么输出救国就会大不一样.
如果你现在不裂解,之后学到方法修改的时候,你就会恍然大悟了.
现在来上手操作一下
新建一个Mac OC X命令行工程
然后你得到了一个main.m文件
在main.m文件中写一句最简单的实例化对象的代码
id obj=[NSObject alloc]init];
//或许你喜欢上面这种写法,但是这里我希望你用下面的写法
//这样我们会更好的看出编译后到底长什么样.
id obj=[NSObject alloc];
obj=[obj init];
保存一下后,用终端cd到这个文件的目录
cd~/Desktop/Runtime/Runtime
然后执行便已命令,编译成C++
clang -rewrite-objc main.m
然后你就可以得到一个main.cpp文件,这就是C++文件了.
打开这个文件,到文件的最后,你可以找到你写的main函数,看看它有什么秘密
id obj=((NSObject *(*)(id,SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"),sel_registerName("allpc"));
obj=((id(*)(id,SEL))(void*)objc_msgSend)((id)obj,sel_registerName("init"));
看不懂 但是可以缩略一下.
首先我们写的第一句话
id obj=[NSObject alloc];
//翻译成C++后
Class classForAlloc=objc_getClass("NSObject");//get class
SEL selForAlloc=sel_registerName("alloc");//get selector
id obj=objc_msgSend(classForAlloc,selForAlloc);//do selector and get obj
1.通过一个字符串创建一个类的结构体指针
2.通过一个字符串创建一个类方法的结构体指针
3.向类结构体发送一个消息,得到一个结果.
之后我们写了另一句话
obj=[obj init];
//翻译后
SEL selForInit=sel_registerName("init");
obj=objc_msgSend(obj,selForInit);
这就是一个简单的消息机制,把面向对象变为面向过程.
我们知道了所有类都是结构体指针,所有的对象也是结构体指针.我们还知道了OC的消息机制.现在我们试图去使用objc/runtime.h文件来进行编程.
创建一个Mac OS X 命令行(为了编译运行快速)工程,在main.m
文件中引入runtime的头文件
#import<objc/runtime.h>
现在你就可以使用runtime里面的方法了.
我们要研究的是类和对象,自然需要一个类和一个对象了.
首先需要一个类,我们自己定义一个类;
@interface ZQPerson@property(copy)NSString *name;
@end
这里我们需要一个obj,就取一个NSArray
类型的对象
#import "ZQPerson"ZQPerson *person=[[ZQFperson alloc]init];
现在你可以进入objc/runtime.h
里面看看有什么公开的函数.
对于那些一看就能看懂用途的函数我就不介绍了,接下来介绍比较常用的功能.
*枚举属性
*关联对象
*方法交换
枚举属性
在操作之前,我们必须要为这个类添加一些属性,以供我们枚举
@interface TRPerson : NSObject@property (nonatomic, copy, readonly) NSString *name;@property (nonatomic, strong) NSObject *obj;@property (nonatomic, weak, setter=resignIdentifier:) id identifier;@property (nonatomic, assign, getter=isRight) BOOL boolValue;@property (nonatomic, assign) CGFloat cgFloat;@property (atomic, assign) CGRect cgRect;@end
回到main.m
文件,现在开始使用runtime.h来枚举这些东西
unsigned int outCount = 0;
objc_property_t *propertyList = class_copuPropertyList([ZQPerson class],&outCount);
for (int i = 0; <outCount; i++){const char *name = property_getName(propertyList[i]);const char *attribute = property_getAttributes(propertyList[i]);NSLog(@"\n name = %s\n attribute = %s",name,attribute);
}
首先看里面的函数函数,
objc_property_t *class_copuPropertyList(Class cls, unsigned int *outCount);
这个函数的作用是枚举出一个类的所有属性
参数一:Class cls 类
参数二:unsigned int *outCount
返回值:objc_property_t
的数组
所以我们给的第一个参数是[ZQPerson class]
第二个参数是为了得到这个数组的长度,所以我们在前面声明了一个变量,并把这个变量的地址传到第二个参数中,函数会自动给他赋值属性个数.
获取到了数组和数组长度,我们就可以通过for循环遍历这个数组了.
在循环中,我们使用了两个方法 第一个是
const char *property_getName(objc_property_t *property);
这个函数可以返回这个属性的名称
另一个函数是
const char *attribute = property_getAttributes(propertyList[i]);
这个函数可以返回这个属性的属性,就是我么你在.h文件中写在”()”中的内容
看看输出结果
2015-11-23 22:09:30.483 temp[900:74089]
name = name
attribute = T@"NSString",R,C,N,V_name2015-11-23 22:09:30.483 temp[900:74089]
name = obj
attribute = T@"NSObject",&,N,V_obj2015-11-23 22:09:30.483 temp[900:74089]
name = identifier
attribute = T@,W,N,SresignIdentifier:,V_identifier2015-11-23 22:09:30.484 temp[900:74089]
name = boolValue
attribute = Tc,N,GisRight,V_boolValue2015-11-23 22:09:30.484 temp[900:74089]
name = cgFloat
attribute = Td,N,V_cgFloat2015-11-23 22:09:30.484 temp[900:74089]
name = cgRect
attribute = T{CGRect={CGPoint=dd}{CGSize=dd}},V_cgRect
现在我们整理一下代码和输出
@property (nonatomic, copy, readonly) NSString *name;
name = name
attribute = T@"NSString",R,C,N,V_name@property (nonatomic, strong) NSObject *obj;
name = obj
attribute = T@"NSObject",&,N,V_obj@property (nonatomic, weak, setter=resignIdentifier:) id identifier;
name = identifier
attribute = T@,W,N,SresignIdentifier:,V_identifier@property (nonatomic, assign, getter=isRight) BOOL boolValue;
name = boolValue
attribute = Tc,N,GisRight,V_boolValue@property (nonatomic, assign) CGFloat cgFloat;
name = cgFloat
attribute = Td,N,V_cgFloat@property (atomic, assign) CGRect cgRect;
name = cgRect
attribute = T{CGRect={CGPoint=dd}{CGSize=dd}},V_cgRect
好的,这样就很明显了,name是一个很好理解的字符串,
所以介绍一下attribute这个字符串
attribute
以T开头
每一个attribute都是以T开头,可以理解为规定
可能包含有@符号
属性类型
@之后就是类型,如果是id就为空,如果不是就是双引号加类名
如果没有@就是基础数据类型,
这理解是一下CGFloat和CGRect
CGFloat是double数据类型,所以是d
而CGRect,有两个成员,一个是CGPoint一个是CGSize
CGPoint 有两个成员,都是 CGFloat,所以有 CGPoint={dd}
同理,CGSize 也有两个 CGFloat,所以有 CGSize={dd}
以此类推,CGRect={CGPoint=dd}{CGSize=dd}
属性属性
通过不同属性的attribute值得比较和OC代码的参考之后的字母可以总结为
字母 | OC | 含义 |
---|---|---|
有R | readonly | 只读 |
无R | readwrite | 读写 |
有N | nonatomic | 线程不安全 |
无N | atomic | 线程安全 |
C | copy | 复制 |
& | strong/retain | 强引用 |
W | weak | 弱引用 |
Sxxx: | setter | set方法 |
Gxxx | getter | get方法 |
Vxxx | var | 实例变量 |
关联对象
关联对象目前比较常用的地方就是给已有的类添加属性和对应的成员变量.
利用Category 给现有的类添加属性
比如我们要给一个NSArray添加一个属性叫做ZQPerson *person
.
在之前的工程中,我们新建一个**OC文件.
File:`Person`File Type:`Category`Class:`NSArray`
然后我们在NSArray+Person.h
里写
#import "TRPerson.h"@interface NSArray (Person)@property (nonatomic, strong) TRPerson *person;@end
于是我们就给NSArray
这个类添加了一个ZQPerson
类型的person
进入main.m
文件试验一下:
NSArray *array = @[@"Magic", @"Unique"];
TRPerson *person = [TRPerson new];
array.person = person;
NSLog(@"%@", array.person);
我们新建了一个NSArray
和一个ZQPerson
,并把person
复制给了array
的属性中.
然后输出看看这个属性是否成功赋值.
于是你很开心的按下了command+r
,发现这家伙崩溃了,崩溃原因:
[__NSArrayI setPerson:]unrecognized selector sent to instance 0x100400d90
NSArray
并没有这个setPerson:
这个方法,仔细一看Xcode还给我们连个警告.
于是我们进入NSArray+Person.m
文件写上get方法和set方法;
#import "NSArray+Person.h"@implementation NSArray (Person)- (void)setPerson:(TRPerson *)person {
_person = person;
}- (TRPerson *)person {
return _person;
}@end
很好,两个错误,因为没有实例变量,或许你觉得可以添加一个扩展,于是你写了一个扩展并且给他添加了一个实例变量ZQPerson *_person
,然后这次连编译都不通过
Category只能给已有的类添加方法,不能添加实例变量
利用Runtime 和Category 给现有的类添加属性
关联对象
关联对象是只将一个对象a利用一个key绑定一个对象b,之后a就可以利用这个key获取到这个对象b
同时a可以二次绑定同一个key,并且会替换之前被绑定的对象,之后再通过key获取对象,就是一个新绑定的值了
是不是感觉和普通的属性很像?可以赋值可以取值,可以重复赋值然后覆盖.
的确,只是调用一个函数而已
函数
Runtime 给了我们两个函数来实现关联对象,只需要 #import
//set function
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);//get function
id objc_getAssociatedObject(id object, const void *key);
负值函数
来看看set函数里的东西
object
要持有“别的对象”的对象,这里也就是指akey
关联关键字,是一个字符串常亮,是一个地址(这里注意,地址必须是不变的,地址不同但是内容相同的也不算同一个key)value
也就是值,你可以猜的出应该是值b了policy
这是一个枚举,你可以点进去看看这个枚举是什么:
OBJC_ASSOCIATION_ASSIGN
OBJC_ASSOCIATION_RETAIN_NONATOMIC
OBJC_ASSOCIATION_COPY_NONATOMIC
OBJC_ASSOCIATION_RETAIN
OBJC_ASSOCIATION_COPY
如果你了解 Objective-C,那你一定知道上面这些枚举的作用了。
所以,我们就可以在前面的NSArray
的分类里这么写
- (void)setPerson:(ZQPerson *)person {
objc_setAssociatedObject(self, "person", person, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
取值函数
现在来看看 get 函数里的东西
- object 持有“别的对象”的对象,这里指a
- key 关联关键字
看完 set 函数之后,get 函数就显而易见了!这里不用多解释,立马就可以写代码
- (TRPerson *)person {
return objc_getAssociatedObject(self, "person");
}
验证结果
运行demo,成功输出如下内容:
2015-11-25 23:18:11.625 temp[745:79654] <TRPerson: 0x100305b60>
说明我们给 array 赋值的结果成功保留下来,下一次去取值可以成功取到上一次保存的值了。
我们会想一下可以发现,OC的对象是有一个结构体指针过程的,结构体指针如下
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;#endif} OBJC2_UNAVAILABLE;
在这里我们可以找到
实例变量struct objc_ivar_list *ivars
方法列表struct objc_method_list **methodLists
缓存方法列表struct objc_cache *cache
当我们向对象发消息的时候,OC会到缓存方法中开始找方法的指针,如果缓存列表中找不到,就会到方法列表中找,如果本类的方法列表中找不到,就会到父类里面找,知道找到方法的指针或者最终的父类NSObject
也找不到方法的指针为止.当找不到方法指针的时候,编译器会发出[xxx 方法]unrecognized selector sent to instance
的警告
当找到方法指针的时候,OC会将在内存中找到方法指针所指向的那个代码块并运行它.
我们知道,程序之所以能运行,是一位方法和变量都存在程序的内存中,所以如果我们改变了方法指针指针所指向的内存地址的内容或者直接改变了方法指针指向的地址,我们就可以改变了方法的实现.
Runtime中的方法交换
Runtime给了我们一个函数来实现方法交换,你只需要导入objc/Runtime.h
文件即可使用这个函数
这个函数是
/**
* Exchanges the implementations of two methods.
* 交换两个方法的实现
*
* @param m1 Method to exchange with second method.
* @param m2 Method to exchange with first method.
*
* @note This is an atomic version of the following:
* 这个函数的实现如下:
* \code
* IMP imp1 = method_getImplementation(m1);
* IMP imp2 = method_getImplementation(m2);
* method_setImplementation(m1, imp2);
* method_setImplementation(m2, imp1);
* \endcode
*/
void method_exchangeImplementations(Method m1, Method m2);
这个方法的注释官方已经给出,我们只要关注他的参数以及返回值(由于返回值为void,所以为此没有多余的解释,主要解释两个参数).
Method
是OC语言中的一个结构体,子啊runtime.h
头文件中有定义.在这个函数中,Method
顾名思义就是要交换的方法.我们可以通过下面这个函数来获取一个类的Method
.
Method class_getInstanceMethod(Class cls, SEL name);
现在这两个参数是我们平时看的见的参数,综上所述,我们只要将两组要交换的方法SEL
和该方法所在的Class
传入进去即可实现方法交换.
由此最终代码会变成
Method m1 = class_getInstanceMethod([M1 class], @selector(method1name));
Method m2 = class_getInstanceMethod([M2 class], @selector(method2name));
method_exchangeImplementations(m1, m2);
如果你不知道方法交换的最终效果,现在我们用一个简单的例子来说明这个问题.
这是两个类的文件,每个类都有自己的方法以及对应的实现部分
(这里的实现部分比较单纯,只是输出一个方法名用作标记).
@interface classOne : NSObject
@end@implementation classOne()
- (void)methodOne {
NSLog(@"one");
}
@end
@interface classTwo : NSObject
@end@implementation classTwo()
- (void)methodTwo {
NSLog(@"two");
}
@end
按常理来说,如果我们调用[[classOne new]methodOne]
则会输出one
.
同理如果调用[[classTwo new]nethodTwo]
则会输出two
.
但是如果我们在某一时刻执行了一次
下面的代码
Method method1 = class_getInstanceMethod([classTwo class], @selector(methodTwo));
Method method2 = class_getInstanceMethod([classOne class], @selector(methodOne));
method_exchangeImplementations(method1, method2);
在此之后(知道程序结束前),我们运行[[classOne new] methodOne]
的时候,打印的是two
.
这个是runtime的黑科技,慎用。例如千万别在一个控制器里写8个通知和写goto。
这个是runtime的黑科技,慎用。例如千万别在一个控制器里写8个通知和写goto。
这个是runtime的黑科技,慎用。例如千万别在一个控制器里写8个通知和写goto。
CocoaTouch 框架是苹果公司仿造Cocoa框架专门为iOS设计的一套SDK
这套SDK没有对外公布源代码,卡法这无法获取到这些SDK的内部实现原理,也无法直接修改这套SDK.
在仅有的面向对象基础上,开发者想修改这些系统提供的类,唯一的方式就是继承
如果开发前期将一些常用的类都做了继承处理,则在开发后期如果出现大范围修改代码就会节省很多事情
比如你要将整个APP的UINavigationBar
做一个统一处理(这里并非指样式统一化,而是一些新逻辑统一化),那你就要将整个APP用到的UINavigationController
都做统一处理,这是一件很费劲的事情.
如果能直接修改系统自带的类就不需要统一继承了
修改系统类要做的最基本的事情就是修改这些类的方法
OC层修改闭源CocoaTouch
你可以尝试使用扩展来做,比如
我们首先使用一个简易的类来模拟苹果提供的类,假装这个类不是我们写的
@interface AppleClass : NSObject@property (nonatomic,copy)NSString *name;@end
然后我们在外面调用这个类的name
的get
方法和set
方法
AppleClass *appleClass = [AppleClass new];appleClass.name = "我是ZQ";NSLog(@"%@",appleClass.name);
现在我们尝试着修改这个AppleClass
的setName
方法.由于这个类”不是我们写的”,所以我们不能再.m
文件里直接修改这个累的方法.
我们可以使用扩展的方法实现
@implementation AppleClass (Modify)
-(void)setName:(NSString *)name{
NSLog(@"这是新的setName:方法");
}
所以我们可以得出一个结论
扩展可以直接修改类中的方法
但是问题来了,我们修改了方法,但是原有的方法功能被我们直接覆盖了.那我们如何保证原有类的方法依旧还在并且还是可以调用呢?
在继承中,重写一个类的方法的时候我们可以使用super
关键字来调用父类的原方法,在这里可以尝试一下.
- (void)setName:(NSString *)name {NSLog(@"这是新的 setName: 方法");[super setName:name];//Xcode在这里报错了
}
这里的super
是NSObject
,他没有setName
方法
显而易见,实现这个方法是AppleClass
而不是NSObject
,所以在AppleClass
中调用他自己的方法应该使用self
而不是super
但是当写成self
就变成了死循环
所以我们无法保留原有类的方法实现,因为我们直接覆盖了
最终结论:
1.扩展可以直接修改原有类的方法,其修改方式是直接覆盖同名方法的实现.
2.分类覆盖方法后无法保留原有方法的实现.
3.如果想让方法原有的功能依旧存在,就不能使用分类来修改类.
如果既要保留原有方法的功能,又想在原有方法里添加我自己的方法怎么办?
在这种情形下,我们可以尝试使用上面的方法交换来达到目的.
(????上面的东西不是可以用继承来做吗? 答:因为我们要做的是拿过来就能给别人用的东西 继承需要开始就写好)
Runtime层修改闭源CocoaTouch
归纳情况
在继承中,如果我们重写父类的方法,一般会使用super
来调用一次父类的方法.最常见的是重写UIViewController
:
@interface MyViewController : UIViewController
@end
@implement MyViewController
-(void)viewDidLoad{[super viewDidLoad];NSLog(@"viewDidLoad 调用完毕");
}
一般这种情况我们灰白调用super
的方法写在整个方法的开头,就如上面一样,但是我们也可以像下面这样,先调用自己的方法,再调用父类的方法.
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- Android APK 签名文件MANIFEST.MF、CERT.SF、CERT.RSA分析
首先我们找一个已经签名的apk文件,修改后缀名为zip,然后解压。可以看到里面有一个META-INF文件夹,里面就是签名验证的文件。有三个文件MANIFEST.MF、CERT.SF、CERT.RSA分别保存着不同的签名信息,下面一个一个来分析:首先是MANIFEST.MF文件,打开MANIFEST.MF文件如下:Mani…...
2024/4/17 13:11:48 - php正则相关知识点
关于正则,其实简单就是搜索和匹配。php,java,python等都是支持正则的,php正则兼容perl。好多同学觉得正则比较难,比较抽象,其实正则是非常简单的,主要是一个熟悉和反复练习的结果,还有一个就是对正则相关知识点的熟练。下面我整理了一下PHP正则需要熟悉的相关知识点,只要…...
2024/4/20 5:39:03 - Android 对登陆页面的美化(一)
对登陆页面的美化(一)对EditeText的美化非常简单的实现浮动标签EditText:Android视图使用EditText之上,并提示EditText时填充文本。核心代码不超过50行先上效果图实现起来很简单,这里用到了一个github的开源组件 floatlabelededittext 和maven库 地址:githubclone或download这…...
2024/5/3 17:53:29 - 100本名著浓缩而成的100句话
1.神要是公然去跟人作对,那是任何人都难以对付的。 (《荷马史诗》) 2.生存还是毁灭,这是一个值得思考的问题。 (《哈姆霄特》) 3.善良人在追求中纵然迷惘,却终将意识到有一条正途。(《浮士德》) 4.认识自己的无知是认识世界的最可靠的方法。 (《随笔集》) 5.你以为我贫…...
2024/4/21 11:08:26 - HTML5离线缓存Manifest是什么
HTML5离线缓存Manifest是什么web app不比PC,有性能和流量方面的考虑,离线应用越来越重要,虽然浏览器有缓存机制,但是时常不靠谱,更何况普通情况下html文件是没法缓存的,断网之后一切over。什么是manifest?简单来说manifest能让你的应用在无网的情况下也能访问。它有三大…...
2024/4/17 13:13:01 - 人生经典定律
一、墨菲定律1949年,一位名叫墨菲的空军上尉工程师,认为他的某位同事是个倒霉蛋,不经意间开了句玩笑:“如果一件事情有可能被弄糟,让他去做就一定会弄糟。”这句话迅速流传,并扩散到世界各地。在流传扩散的过程中,这句笑话逐渐失去它原有的局限性,演变成各种各…...
2024/4/17 13:12:49 - SAP CDS view(Core Data Service)自学的一些材料和方法
Self study和incident handling的不同之处 (1) incident handling有时间压力,遇到自己思路卡住求助同事无可厚非。而Self study没有太大的时间压力,要充分利用这个机会提高自己的学习能力。 (2) incident handling目标明确 - 解决issue。而self study - 学到什么程度?拿我自…...
2024/4/17 13:12:55 - php 正则匹配的src路径
#src="([^"]*?)"[^>]*?#is 转载于:https://www.cnblogs.com/i6010/articles/4319190.html...
2024/4/17 13:13:01 - c语言学习—图书搜索
请问下:你说的C四大圣经指那几本啊?——《C 陷阱与缺陷》 && 《C程序设计语言》 && 《C专家编程》 && 《C和指针》&& 《你必须知道的495个C语言问题》 && 《C语言深度剖析》 && 《C标准库》 ???/这基本可以互补性的 看,…...
2024/4/20 13:03:05 - 60个有用的规则
1、蓝斯登原则:在你往上爬的时候,一定要保持梯子的整洁,否则你下来时可能会滑倒。 提出者:美国管理学家蓝斯登。 点评:进退有度,才不至进退维谷;宠辱皆忘,方可以宠辱不惊。 2、卢维斯定理:谦虚不是把自己想得很糟,而是完全不想自己。 提出者:美国心理学家…...
2024/4/17 13:13:06 - php正则替换所有空格和换行
替换所有空格为空$contents=" abc "; $contents=preg_replace(/\s+/,,$contents); //结果$contents="abc";替换所有换行符$contents = str_replace(array("\r\n", "\r", "\n"), "", $contents);匹配…...
2024/3/31 19:26:43 - SAP系统中的区域菜单(Area Menu)及SPRO的使用技巧
在SAP系统中,有着几万个不同的事务代码,虽然在系统的导航页面,SAP已经按照功能和模块将不同的事务组织了起来,但寻找特定某一功能相关的事务时,我们还是不得不通过菜单的层级结构,一层一层地去寻找事务代码。在本篇博客中,我将介绍SAP系统中的区域菜单(Area Menu)的概念…...
2024/4/17 13:12:54 - unity5 manifest
https://www.cnblogs.com/lancidie/p/5878789.html之前曾经写了一篇博客介绍Unity5的AssetBundle,结果似乎很受关注。不过似乎很多人看了之后都不懂,主要是因为不太明白AssetBundle是什么,它的依赖关系和结构是什么的,就直接想拿代码去用,而导致了很多人说看不懂啊,说什么…...
2024/4/17 13:12:55 - 提升宝宝智力的方法和惩罚宝宝的科学方法
最近有太多的朋友升级为孩奴,先恭喜他们! 一.提高宝宝逻辑性1、考推理你和宝宝准备一起吃早点了,但还没有把早饭盒揭开,父母可让孩子猜一猜:“猜猜看,咱们今天早点吃什么?”“你希望是牛奶还是豆浆?”这种方法可提升孩子的数学逻辑智能。2、数数楼梯的台阶上下楼梯会让…...
2024/4/17 13:13:19 - php正则表达式提取数字,字符串中提取数字
<?php$str = "请注意:有谁知道30901.5号路怎么走?这个因为我买了100块的烧饼和7901的钥匙了,那个对了,我再拿个30000";$pattern = /(\d+\.?\d+)/;//$pattern = /(\d+)\.?(\d+)/;// $str = "42.234 EUR 53.218 AUD CAD97.164 311.151 MYR 125.042 NZD …...
2024/4/17 13:12:00 - 用MFC做漂亮界面之美化按钮(PNG透明贴图)
上次我们学习了如何美化对话框的界面,这次我们为上次的对话框添加两个按钮,一个是关闭按钮,另一个是最小化按钮,好,现在我们先看一下效果:是不是很难看,因为我们的对话框美化了,所以我们的按钮也要美化,因为采用贴图的方式来美化,所以,我先给出这两个按钮的PNG格式的…...
2024/3/31 19:26:37 - 面向SAP实施的IBM BPM智慧流程
2019独角兽企业重金招聘Python工程师标准>>> 面向SAP实施的IBM BPM智慧流程 IBM BPM for SAP的能力帮助客户利用SAP以提供端到端的业务流程管理。BPM为SAO项目实施带来的核心价值。对其内容详细阅读转载于:https://my.oschina.net/u/856019/blog/155192...
2024/4/17 23:05:21 - PHP正则匹配字符串中的中文字符串并返回
preg_match_all("/[\x{4e00}-\x{9fa5}]+/u","字符串",$regs)preg_match_all("正则表达式","截取的字符串","成功之后返回的结果集(数组)")返回字符串:字符串 = implode(",", $regs[0])...
2024/4/25 5:21:30 - "由于应用程序配置不正确,应用程序未能启动" VS2008 Release /MD编译
原文地址:http://blog.sina.com.cn/s/blog_48f93b530100ix0a.html问题描述: 用VS2008 Release /MD模式编译了一个可执行程序,程序依赖的CRT库和对应的manifest文件也都拷贝到了程序所在目录,大部分系统都可以正常打开,但是在一些xp系统上却出现如下对话框: 最简单的办法可以…...
2024/4/20 9:49:18 - C语言学习的经典书籍--转载
推荐前言: 原文出处:http://book.douban.com/doulist/338101/ 和其他语言相比(例如C++),C语言是一门比较“小”的语言,可以在较短的时间内入门。但是由于C的很强的表达能力和太多的细枝末节,要想精通比较困难。要做到精通有3种途径: 1)阅读经典书籍,只读经典。 2)多看…...
2024/4/12 2:03:43
最新文章
- webpack 常用插件
clean-webpack-plugin 这个插件的主要作用是清除构建目录中的旧文件,以确保每次构建时都能得到一个干净的环境。 var { CleanWebpackPlugin } require("clean-webpack-plugin") const path require("path");module.exports {mode: "de…...
2024/5/3 20:42:33 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 汽车疲劳测试试验平台技术要求(北重厂家)
汽车疲劳测试试验平台技术要求通常包括以下几个方面: 车辆加载能力:测试平台需要具备足够的承载能力,能够同时测试多种车型和不同重量的车辆。 动力系统:测试平台需要具备稳定可靠的动力系统,能够提供足够的力和速度来…...
2024/5/3 8:56:17 - jQuery(一)
文章目录 1. 基本介绍2.原理示意图3.快速入门1.下载jQuery2.创建文件夹,放入jQuery3.引入jQuery4.代码实例 4.jQuery对象与DOM对象转换1.基本介绍2.dom对象转换JQuery对象3.JQuery对象转换dom对象4.jQuery对象获取数据获取value使用val()获取…...
2024/5/1 13:36:17 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/1 17:30:59 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/2 16:16:39 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/29 2:29:43 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/2 9:28:15 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/27 17:58:04 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/27 14:22:49 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/28 1:28:33 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/30 9:43:09 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/27 17:59:30 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/2 15:04:34 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/28 1:34:08 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/26 19:03:37 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/29 20:46:55 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/30 22:21:04 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/1 4:32:01 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/27 23:24:42 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/28 5:48:52 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/30 9:42:22 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/2 9:07:46 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/30 9:42:49 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57