NSObject应该都不陌生,大多数类层次结构的根类,子类从根类继承到运行时系统的基本接口和作为Objective-C对象的行为能力。
Initializing
+ (void)initialize;
+ (void)load;
这俩个方法都是在类初始化的时候调用的。
关于+ (void)initialize
- 在类或者继承它的类第一次初始化的时候调用该方法,而且只会初始化一次。超类比子类先接受该方法,且不需要调用
[super initialize]
- 这个方法是线程安全的。也就是说,如果在初始化中向该类发送消息会导致线程阻塞,直到初始化完成
- 如果子类没有实现初始化,可以多次调用超类实现 - 运行时将调用继承的实现 - 或者如果子类显式调用
[super initialize]
。如果想保护自己不被多次运行,可以按照以下方式构建您的实现:
+(void)initialize{
if(self == [ClassName self]){
// ...初始化......
}
}
4.initialize
是以阻塞方式调用的,方法实现限制为尽可能少的必要工作量。具体来说,任何采用其初始化方法中其他类可能需要的锁的代码都可能导致死锁。该方法应该限制为简单的类本地初始化
关于+(void)load
- 所有添加到
compile sources
中的文件或动态加载或FrameWork
中的类和类别都会实现该方法(a. 所有超类的load
方法之后调用类的load
方法。b. 类自己的+ load
方法之后调用category + load
方法。c. 且不需要调用[super load]
) - 同时实现
load
和initialize
方法的时候,先执行load
- 在自定义
load
中,可以发送其他不相关的类,可能这些类的load
尚未运行
一般情况下执行交换方法的时候会实现该方法,其他情况不建议调用
Creating, Copying, and Deallocating Objects
+ (instancetype)alloc;// 返回一个新的实例
+ (instancetype)allocWithZone:(struct _NSZone *)zone; // zone 参数被忽略
+ (instancetype)new;
- (instancetype)init;
新实例的isa
实例变量被初始化为描述类的数据结构;所有其他实例变量的内存设置为0。
必须使用init…方法来完成初始化过程。例如:
Class *newObject =[[Class alloc] init];
不要覆盖alloc
和allocWithZone:
来包含初始化代码。相反,实现init的类特定版本……方法。
init
初始化对象
new
相当于[[Class alloc] init]
- (id)copy;
- (id)mutableCopy;
+ (id)copyWithZone:(struct _NSZone *)zone;
+ (id)mutableCopyWithZone:(struct _NSZone *)zone;
此方法的存在使类对象可以在需要符合NSCopying
或NSMutableCopying
协议的对象的情况下使用,不建议重写该方法
- (void)dealloc;
实例释放的时候调用释放实例变量之外的资源,例如
- (void)dealloc {
free(myBigBlockOfMemory);
}
在dealloc的实现中,不要调用超类的实现。应该尽量避免使用dealloc管理有限资源的生命周期,例如文件描述符。
Identifying Classes
+ (Class)class;
返回类对象
+ (Class)superclass;
返回类的超类
+ (BOOL)isSubclassOfClass:(Class)aClass;
判断类是否是aClass
的子类
测试类的功能
+ (BOOL)instancesRespondToSelector:(SEL)aSelector;
类实例是否能够响应给定的选择器。如果将aSelector消息转发给其他对象,则类的实例能够接收到这些消息而不会出错,即使该方法返回NO。要询问类是否可以响应特定的消息,实现respondsToSelector:
。
+ (BOOL)conformsToProtocol:(Protocol *)protocol;
指示类是否符合给定的协议,如果是协议遵循协议,也是返回YES
获取关于方法的信息
- (IMP)methodForSelector:(SEL)aSelector;
定位并返回方法的接收者实现的地址,以便将其作为函数调用。
aSelector
,用于标识返回实现地址的方法。aSelector
必须是有效的和非空的。可以在将选择器传递给methodForSelector:
之前,使用respondsToSelector:
方法进行检查。
如果接收方是实例,则aSelector应引用实例方法;如果接收者是一个类,它应该引用一个类方法。
+ (IMP)instanceMethodForSelector:(SEL)aSelector;
定位并返回由给定选择器标识的实例方法的实现的地址。
如果接收方的实例不能响应aSelector消息,则会生成错误。
+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector;
返回一个NSMethodSignature
对象,该对象包含由给定aSelector
的实例方法的描述,如果找不到方法,返回nil。
关于NSMethodSignature
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
此方法用于协议的实现。此方法还用于必须创建NSInvocation
对象的情况,例如在消息转发期间。如果调用了没有实现的方法,可以通过重写此方法进行消息转发。例如:
//首先发送 -methodSignatureForSelector: 消息获得函数的参数和返回值类型。如果 -methodSignatureForSelector: 返回 nil ,Runtime 则会发出 -doesNotRecognizeSelector: 消息,程序这时也就挂掉了。如果返回了一个函数签名,Runtime 就会创建一个 NSInvocation 对象并发送 -forwardInvocation: 消息给目标对象。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
if (aSelector == @selector(funck)) {
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
return nil;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
// NSInvocation 实际上就是对一个消息的描述,包括selector 以及参数等信息。所以你可以在 -forwardInvocation: 里修改传进来的 NSInvocation 对象,然后发送 -invokeWithTarget: 消息给它,传进去一个新的目标:
SEL sel = anInvocation.selector;
PSFastForwarding *fast = [PSFastForwarding new];
if ([fast respondsToSelector:sel]) {
[anInvocation invokeWithTarget:fast];
} else {
[self doesNotRecognizeSelector:sel];
}
}
Describing Objects
+ (NSString *)description;
返回一个字符串,该字符串表示接收类的内容(如果不重写 只打印类的名字)。
Discardable Content Proxy Support
@property(readonly, retain) id autoContentAccessingProxy;
设置对象的代理(没用过。。)
Sending Messages
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
用默认模式在当前线程延时执行方法
此方法设置一个计时器,以在当前线程的运行循环上执行aSelector消息。计时器被配置为以默认模式(NSDefaultRunLoopMode
)运行。当计时器触发时,线程尝试从运行循环中退出消息队列并执行选择器。如果运行循环正在运行且处于默认模式,则成功;否则,计时器将等待,直到运行循环处于默认模式。
此方法注册其当前上下文的runloop,并依赖于该runloop定期运行以正确执行。当调度队列调用此方法时,您可能会遇到一个常见的上下文,在此上下文中,您可能会使用一个不定期自动运行的runloop进行注册。如果在调度队列上运行时需要此类功能,则应该使用
dispatch_after
和相关方法来获得所需的行为。
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray<NSRunLoopMode> *)modes;
在指定models
用默认模式在当前线程延时执行方法
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
使用默认模式在主线程上调用方法。
arg
:当方法被调用时传递给它的参数。如果方法不接受参数,则传递nil。
wait
:一个布尔值,指定当前线程是否阻塞,直到在主线程上的接收器上执行指定的选择器之后。指定YES来阻止这个线程;否则,指定NO立即返回此方法。
如果当前线程也是主线程,并且您传递YES,则消息将立即执行,否则执行将排队通过运行循环在下一次运行。
主线程包含应用程序的主运行循环,是NSApplication
对象接收事件的地方。本例中的消息是您希望在线程上执行的当前对象的方法。
此方法使用公共运行循环模式(即与NSRunLoopCommonModes
常量关联的模式)在主线程的运行循环上对消息进行队列。作为其正常运行循环处理的一部分,主线程将消息脱队列(假设它以一种常见的运行循环模式运行)并调用所需的方法。来自同一线程的多个对该方法的调用会导致相应的选择器排队,并按照调用的相同顺序执行。
不能使用此方法取消排队的消息。如果希望取消当前线程上的消息,必须使用performSelector:withObject:afterDelay:
或performSelector:withObject:afterDelay:inModes: method
。
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;
使用指定的模式在主线程上调用接收器的方法。
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;
使用默认模式在指定线程上调用接收器的方法。
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
在新的后台线程上调用接收器的方法。
此方法在应用程序中创建一个新线程,如果应用程序还没有多线程模式,则将其放入多线程模式。由aSelector表示的方法必须设置线程环境,就像为程序中的任何其他新线程所做的那样。
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;
取消执行先前注册到performSelector:with object:afterDelay: instance
方法中的请求。
所有具有相同目标aTarget的执行请求都将被取消。此方法仅在当前运行循环中删除执行请求,而不是在所有运行循环中删除。
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument;
取消执行先前注册到performSelector:with object:afterDelay:
的请求。
Forwarding Messages
- (id)forwardingTargetForSelector:(SEL)aSelector;
返回未识别的消息应首先指向的对象。
如果一个对象实现(或继承)这个方法,并返回一个非nil(和非
self
)结果,则返回的对象将用作新的接收方对象,消息分派将恢复到该新对象。(显然,如果从这个方法返回self,代码就会陷入无限循环。)
如果在非根类中实现此方法,类对于给定的选择器没有任何要返回的内容,那么应该返回调用super实现的结果。
只是想将消息重定向到另一个对象,并且比常规转发快一个数量级时,非常有用。如果转发的目标是捕获NSInvocation
,或者在转发过程中操作参数或返回值,则此方法是无效的。
- (void)forwardInvocation:(NSInvocation *)anInvocation;
被子类重写以将消息转发到其他对象。
当向对象发送其没有相应方法的消息时,运行时系统为接收者提供将消息委托给另一个接收者的机会。 它通过创建表示消息的NSInvocation
对象并向接收方发送包含此NSInvocation
对象作为参数的forwardInvocation:
消息来委派消息。 接收者的forwardInvocation:
方法然后可以选择将消息转发到另一个对象。 (如果该对象也无法响应该消息,它也将有机会转发它。)
因此,forwardInvocation:
消息允许对象与其他对象建立关系,对于某些消息,这些对象将代表它行动。 在某种意义上,转发对象能够“继承”它转发消息的对象的一些特征。
要响应对象本身不认识的方法,必须覆盖
methodSignatureForSelector:
以及forwardInvocation:。
转发消息的机制使用methodSignatureForSelector
获得的信息:创建要转发NSInvocation
对象。重写方法必须为给定的选择器提供适当的方法签名,方法可以是预先构造一个方法,也可以是为另一个对象请求一个方法签名。
forwardInvocation:
方法的实现有两个任务:
- 查找可以响应
anInvocation
中编码的消息的对象。对于所有消息,此对象不必相同。 - 使用
anInvocation
将消息发送到该对象。anInvocation
将保存结果,运行时系统将提取并将此结果传递给原始发件人。
在简单的情况下,对象将消息转发到一个目的地(例如下面示例中的假设的朋友实例变量),forwardInvocation:
方法可以像这样简单:
- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL aSelector = [invocation selector];
if([friend respondsToSelector:aSelector])
[invocation invokeWithTarget:friend];
else
[super forwardInvocation:invocation];
}
转发的消息必须具有固定数量的参数;不支持可变数量的参数(采用printf()的样式)。
转发邮件的返回值将返回给原始发件人。可以将所有类型的返回值传递给sender:
id类型,结构,双精度浮点数。
forwardInvocation:
方法的实现不仅可以转发消息。 例如,可用于合并响应各种不同消息的代码,从而避免必须为每个选择器编写单独的方法。 forwardInvocation:
方法也可能涉及对给定消息的响应中的其他几个对象,而不是将其转发给一个消息。
NSObject
的forwardInvocation
实现:只需调用doesNotRecognizeSelector:
方法;它不转发任何消息。因此,如果您选择不实现forwardInvocation:
,则向对象发送无法识别的消息将引发异常。
Dynamically Resolving Methods
+ (BOOL)resolveClassMethod:(SEL)sel;
动态地为类方法的给定选择器提供实现。
如果找到方法并将其添加到接收方,则为YES,否则为NO。
此方法允许动态地为给定的选择器提供实现
+ (BOOL)resolveInstanceMethod:(SEL)sel;
动态地为实例方法的给定选择器提供实现。
Objective-C
方法就是一个C
函数,它至少有两个参数self
和_cmd
。使用class_addMethod
函数,可以将函数作为方法添加到类中。给定以下函数:
void dynamicMethodIMP(id self, SEL _cmd)
{
// implementation ....
}
使用resolveInstanceMethod:
将它作为一个方法动态地添加到类中(称为resolveThisMethodDynamically
),如下所示:
+ (BOOL) resolveInstanceMethod:(SEL)aSEL
{
if (aSEL == @selector(resolveThisMethodDynamically))
{
// IMP insertIMP = imp_implementationWithBlock(^(id _self){ \
DebugLog(@"_doing foo");// 这样也行
});
class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
return YES;
}
return [super resolveInstanceMethod:aSel];
}
在调用
Objective-C
转发机制之前调用此方法。如果respondsToSelector:
或instancesRespondToSelector:
被调用,则动态方法解析器将有机会首先为给定的选择器提供一个IMP
。
- (void)doesNotRecognizeSelector:(SEL)aSelector;
方法识别不了
只要对象收到无法响应或转发的aSelector
消息,运行时系统就会调用此方法。反过来,此方法引发NSInvalidArgumentException
,并生成错误消息。
任何doesNotRecognizeSelector:
消息通常仅由运行时系统发送。但是,它们可以在程序代码中使用,以防止方法被继承。例如,NSObject
子类可以通过重新实现它来包含didNotRecognizeSelector:
消息来放弃copy
或init
方法,如下所示:
- (id)copy
{
[self doesNotRecognizeSelector:_cmd];
}
_cmd
变量是传递给当前选择器的每个方法的隐藏参数;在此示例中,它标识了复制方法的选择器。此代码防止子类的实例响应来自转发复制消息的复制消息或超类 - 尽管respondsToSelector:
仍将报告接收者可以访问复制方法。
如果重写此方法,则必须在实现结束时调用super
或引发NSInvalidArgumentException
异常。换句话说,这种方法不能正常返回;它必须始终导致抛出异常。
Archiving
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
由子类重写,以替换另一个对象,以取代已解码并随后接收此消息的对象。
可以使用此方法消除编码器创建的冗余对象。例如,如果在解码一个对象之后,您发现一个等效的对象已经存在,那么您可以返回现有的对象。如果返回替换,则覆盖方法负责释放接收方。
此方法由NSCoder
调用。NSObject
的实现只返回self
。
@property(readonly) Class classForArchiver;
在存档期间替换接收方自己的类的类。
@property(readonly) Class classForCoder;
在编码过程中被子类重写以替换自己的类之外的类。
@property(readonly) Class classForKeyedArchiver;
子类,以在键控存档期间用新类替换实例。
对象将被编码为类的成员。此属性由encoder类和类编码表的实例名覆盖。如果此属性为nil,则忽略此属性的结果。
+ (NSArray<NSString *> *)classFallbacksForKeyedArchiver;
如果类不可用,则返回可用于解码对象的类的名称。
NSKeyedArchiver
调用这个方法并将结果存储在归档文件中。如果在解压缩时对象的实际类不存在,NSKeyedUnarchiver
将遍历存储的类列表,并使用第一个存在的类作为解压缩对象的替代类。这个方法的默认实现返回一个空数组。
如果在应用程序中引入了一个新类,以便在没有该类的系统上读取存档时提供向后兼容性,则可以使用此方法。有时可能会有另一个类可能工作近以及这个新类的替代品,和存档键和归档状态为新类可以精心挑选的对象(或兼容性写入),这样在必要时可以作为替代类从未归档。
+ (Class)classForKeyedUnarchiver;
在键控解存档期间被子类重写以替换新类。
在键控解存档期间,接收方的实例将被解码为返回类的成员。此方法将解码器的类和实例名的结果覆盖到类编码表。
- (id)replacementObjectForCoder:(NSCoder *)aCoder;
被子类覆盖,以便在编码过程中替换另一个对象。
对象可以将自身编码为归档文件,但如果要将其编码为分发,则为其本身编码代理。此方法由NSCoder
调用。NSObject
的实现返回self
。
- (id)replacementObjectForKeyedArchiver:(NSKeyedArchiver *)archiver;
在键控存档期间被子类重写以替换另一个对象。
只有在编码器中没有设置对象的替换映射时才调用此方法(例如,由于前面调用
replacementObjectForKeyedArchiver:
到该对象)。
+ (void)setVersion:(NSInteger)aVersion;
设置接收方的版本号。当类的实例要存档并在以后重用时,版本号很有用。默认版本是0。
版本号适用于
NSArchiver/NSUnarchiver
,但不适用于NSKeyedArchiver/NSKeyedUnarchiver
。键控归档器不对类版本号进行编码。
+ (NSInteger)version;
返回分配给该类的版本号。
如果没有设置版本,默认值是0。
解码或解压需要版本号,这样才能正确地检测和解码对象的旧版本。
当从NSCoding
协议或其他方法中获取版本时,应该谨慎。在获取类版本号时显式使用类名:
version = [MyClass version];
不要简单地将版本发送到类a的返回值,可能会返回子类的版本号。
Instance Properties
@property(nonatomic) CGPoint accessibilityActivationPoint;
屏幕坐标中可访问性元素的激活点。
此属性的默认值是可访问性元素的框架的中点,由accessibilityFrame
属性给出。元素的激活点是当用户双击该元素时VoiceOver
激活的特定区域。
指定激活点的能力允许元素在不同的环境中以不同的方式呈现给VoiceOver
,而不需要改变元素呈现自身的方式。例如,主屏幕应用程序图标的标准激活点是图标的中点。但是,当用户重新排列主屏幕上的图标时,激活点变为remove
控件的中点(即图标左上角的圆圈X)。
使用此属性可确保小元素的激活点保持准确,即使您将该元素的大图显示给VoiceOver
。
@property(nonatomic, copy) NSAttributedString *accessibilityAttributedHint;
@property(nonatomic, copy) NSAttributedString *accessibilityAttributedLabel;
@property(nonatomic, copy) NSAttributedString *accessibilityAttributedValue;
@property(nonatomic) UIAccessibilityContainerType accessibilityContainerType
@property(nonatomic, retain) NSArray<UIAccessibilityCustomRotor *> *accessibilityCustomRotors;
@property(nonatomic, copy) NSArray<UIAccessibilityLocationDescriptor *> *accessibilityDragSourceDescriptors;
@property(nonatomic, copy) NSArray<UIAccessibilityLocationDescriptor *> *accessibilityDropPointDescriptors;
@property(nonatomic, copy) NSArray *accessibilityHeaderElements;
@property(readonly, getter=isSelectable) BOOL selectable;
官方没有给出解释
@property(nonatomic, strong) NSArray<UIAccessibilityCustomAction *> *accessibilityCustomActions;
要显示的自定义操作数组以及内置操作。
该数组包含一个或多个定义支持的操作的UIAccessibilityCustomAction对象。辅助技术,如VoiceOver
,在适当的时候向用户显示自定义操作。
@property(nonatomic, strong) NSArray *accessibilityElements;
容器中可访问性元素的数组。容器可以实现此属性,而不是支持检索所包含元素的动态方法。此属性的默认值为nil。
@property(nonatomic) BOOL accessibilityElementsHidden;
一个布尔值,指示此可访问性元素中包含的可访问性元素是否隐藏。
此属性的默认值是NO。您可以使用此属性来隐藏新视图到达时所覆盖的视图。在这种情况下,隐藏的视图可能在屏幕上仍然可见,但它们不是用户操作的焦点。
您还可以使用此属性来隐藏VoiceOver
用户不需要注意的临时视图。例如,VoiceOver
不需要描述用户调整设备音量时出现的半透明视图,因为这个动作的听觉反馈就足够了。
@property(readonly, strong) id accessibilityFocusedUIElement;
具有焦点的可访问性层次结构的最深层后代。
您可以假设对焦点的搜索已经缩小到可访问性元素。通过标识可能具有焦点的子元素(如果有的话),覆盖此方法来进行更深入的搜索。如果子元素没有焦点,则返回self,如果可用,则调用超类的实现。默认的NSView和NSCell实现测试可访问性元素是否是被忽略的元素,如果是,返回元素的第一个未被忽略的父元素;否则它们返回self
@property(nonatomic) CGRect accessibilityFrame;
可访问性元素的框架,在屏幕坐标中。
这个属性的默认值是CGRectZero
,除非接收者是UIView
对象或UIView
的子类,在这种情况下,值是视图的框架。
你必须为一个易访问性元素设置这个属性,它代表一个不是UIView子类的对象,因为这样一个对象的屏幕坐标是未知的。(你不需要为代表UIView子类的易访问性元素设置这个属性,因为这样一个对象的屏幕坐标是已知的。)
@property(nonatomic, copy) NSString *accessibilityHint;
在本地化字符串中对易访问性元素执行操作的结果的简要描述。
此属性的默认值为nil,除非接收方是UIKit控件,在这种情况下,该值是基于控件类型的系统提供的提示。
@property(nonatomic, copy) NSString *accessibilityLabel;
在本地化字符串中标识可访问性元素的简洁标签。
除非接收方是UIKit控件,否则此属性的默认值为nil,在这种情况下,该值是从控件标题派生的标签。
注意
如果提供UIImage
对象以在UISegmentedControl
中显示,请在每个图像上设置此属性以确保可以正确访问这些段。
如果实现自定义控件或视图,或者在UIKit控件上显示自定义图标,请设置此属性以确保可访问性元素具有适当的标签。如果辅助功能元素未显示描述性标签,请将此属性设置为提供简洁的本地化标签,以简洁地标识该元素。例如,“播放音乐”按钮可能会显示一个图标,显示有视力的用户所做的事情。但是,为了便于访问,该按钮应具有可访问性标签“播放”或“播放音乐”,以便辅助应用程序可以向残障用户提供此信息。但请注意,标签不应包含控件类型(例如“按钮”),因为此信息包含在与辅助功能元素关联的特征中。
@property(nonatomic, strong) NSString *accessibilityLanguage;
可访问性元素的标签、值和提示使用的语言。
此属性的默认值为nil。如果没有设置语言,则使用用户的当前语言设置。如果需要设置此属性,请确保使用符合BCP 47规范中定义的格式的语言ID标记。
@property(nonatomic) UIAccessibilityNavigationStyle accessibilityNavigationStyle;
应用于对象及其元素的导航样式。
一些辅助技术允许用户选择父视图或容器来导航其元素。此属性控制该行为是否适用于当前对象。开关控制使用这种技术,但VoiceOver和其他辅助技术不使用。
这个属性的默认值是UIAccessibilityNavigationStyleAutomatic
。
@property(readonly) BOOL accessibilityNotifiesWhenDestroyed;(macOS 10.9+)
一个布尔值,指示自定义可访问性对象在销毁其相应的UI元素时是否发送通知。
@property(nonatomic, copy) UIBezierPath *accessibilityPath;
元素在屏幕坐标中的路径。
此属性的默认值为nil。如果没有设置路径,则使用可访问性框架矩形突出显示元素。
当您为该属性指定值时,辅助技术将使用您指定的路径对象(除了可访问性框架之外,而不是替代它)来突出显示元素。
@property(nonatomic) UIAccessibilityTraits accessibilityTraits;
最能描述可访问性元素的可访问性特征的组合。
该属性的默认值是UIAccessibilityTraitNone
,除非接收方是UIKit
控件,在这种情况下,该值是与控件相关的特征的标准集。
如果实现自定义控件或视图,则需要选择最能描述对象的所有可访问性特征,并通过执行or操作将它们与超类的特征(换句话说,与超. accessibilitytraits
)结合起来。有关特征的完整列表,请参见可访问性特征。
@property(nonatomic, copy) NSString *accessibilityValue;
可访问性元素在本地化字符串中的值。
这个属性的默认值是nil,除非接收者是UIKit控件,在这种情况下,当它与标签不同时,属性的值表示控件的值。
当易访问性元素具有静态标签和动态值时,设置此属性以返回该值。例如,尽管表示文本字段的可访问性元素可能具有标签“Message”,但其值是文本字段中当前的文本。
@property(nonatomic) BOOL accessibilityViewIsModal;
一个布尔值,指示VoiceOver
是否应忽略视图中与接收器相同的元素。
此属性的默认值是NO。当该属性的值为YES时,VoiceOver将忽略接收视图的兄弟视图中的元素。
例如,在一个包含兄弟视图窗口a和B, accessibilityViewIsModal
设置为YES视图B导致画外音忽略视图中的元素a .另一方面,如果视图B包含子视图C和C你设置accessibilityViewIsModal
是的视图,画外音不忽略元素视图。
@property(nonatomic) BOOL isAccessibilityElement;
返回一个数组,该数组包含接收方公开的绑定。
子类可以重写此方法,以删除由不适合子类的超类公开的绑定。
@property(nonatomic) BOOL isAccessibilityElement;
一个布尔值,指示接收器是否是辅助应用程序可以访问的可访问元素。
这个属性的默认值是NO,除非接收者是一个标准的UIKit控件,在这种情况下,值是YES。
辅助应用程序只能获得由可访问性元素表示的对象的信息。因此,如果实现了残疾用户应该可以访问的自定义控件或视图,则将此属性设置为YES。此实践的唯一例外是,视图仅作为应该可访问的其他项的容器。这样的视图应该实现UIAccessibilityContainer
协议,并将此属性设置为NO。
@property void *observationInfo;
一个指针,用于标识与被观察对象注册的所有观察者、注册时使用的选项等有关的信息。
该方法的默认实现从内存地址键控的被观察对象的全局字典中检索信息。
为了提高性能,可以重写此属性和observationInfo,以便将不透明的数据指针存储在实例变量中。此属性的重写不能尝试向存储的数据发送消息。
@property(nonatomic) BOOL shouldGroupAccessibilityChildren;
一个布尔值,指示VoiceOver是否应该将接收方的子元素(无论它们在屏幕上的位置如何)分组在一起。
此属性的默认值是NO。
例如,考虑一个在垂直列中显示项目的应用程序。通常,VoiceOver
会在水平行中导航这些项。在垂直列中的项目的父视图中将此属性的值设置为YES
,会使VoiceOver
尊重应用程序的分组并正确导航它们。
Type Properties
@property(class, readonly) BOOL accessInstanceVariablesDirectly;
返回一个布尔值,该值指示键值编码方法在未找到属性的访问器方法时是否应直接访问相应的实例变量。
默认返回YES。子类可以重写它以返回NO,在这种情况下,键值编码方法将不会访问实例变量。
Instance Methods
- (BOOL)accessibilityActivate;
告诉元素激活自身并报告操作的成功或失败。
使用此方法使用户更容易访问复杂的控件。当VoiceOver用户双击选中的元素时,可访问性系统调用此方法。这个方法的实现应该激活元素并执行它认为合适的任何其他任务。例如,您可能使用该方法来激活一个需要复杂手势的控件,而VoiceOver用户很难执行该控件,这可能是因为该手势在VoiceOver运行时具有不同的含义。
在执行任何任务之后,返回一个适当的布尔值来指示成功或失败。
- (void)accessibilityDecrement;
告诉易访问性元素递减其内容的值。
如果元素具有uiaccessibilitytraitzable
特性,则必须实现此方法。使用此方法递减元素的值。例如,UISlider
对象使用此方法以适当的数量递减其值。
- (id)accessibilityElementAtIndex:(NSInteger)index;
指定索引处的可访问性元素,如果不存在则为nil。
- (NSInteger)accessibilityElementCount;
可访问性元素的数量。默认情况下,该方法返回0。
- (void)accessibilityElementDidBecomeFocused;
在辅助技术将其虚拟焦点设置为可访问性元素之后发送。
如果需要知道辅助技术何时将其虚拟焦点放在可访问性元素上,重写accessibilityElementDidBecomeFocused
。
- (void)accessibilityElementDidLoseFocus;
在辅助技术将其虚拟焦点从可访问性元素中移除之后发送。
如果需要知道辅助技术何时从可访问性元素中删除了其虚拟焦点,请覆盖accessibilityElementDidLoseFocus
。注意,accessibilityElementDidLoseFocus
是在accessibilityElementDidBecomeFocused
之前发送的。
- (BOOL)accessibilityElementIsFocused;
如果辅助性技术实际上关注的是元素,返回YES
- (void)accessibilityIncrement;
告诉易访问性元素增加其内容的值。
如果元素具有uiaccessibilitytraitzable
特性,则必须实现此方法。使用此方法递增元素的值。例如,UISlider
对象使用此方法以适当的数量递增其值。
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
注册观察者对象以接收与接收此消息的对象相关的键路径的KVO通知。
接收此消息的对象和观察者都不会被保留。调用此方法的对象最终还必须调用removeObserver:forKeyPath:
或removeObserver:forKeyPath:context:
方法,以便在参与KVO时注销观察者。
- (BOOL)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex;
实现从应用程序模式对话框中记录的错误中恢复。当在应用程序模式对话框中向用户显示错误警告,并且用户选择了error指定的错误恢复选项时调用。
- (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo;
实现从文档模式表中记录的错误中恢复。
在文档模式表中向用户显示错误警报时调用,并且用户已选择错误指定的错误恢复选项。 尝试恢复后,您的实现应该向委托发送didRecoverSelector
中指定的消息,并传递提供的contextInfo
。
didRecoverSelector
应具有以下签名:
- (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo;
如果错误恢复尝试成功,didRecover
为YES; 否则它是NO。
- (void)awakeFromNib;
从Interface Builder
存档或nib
文件加载后,进行修改
加载nib
的基础结构向从nib存档重新创建的每个对象发送一个awakeFromNib
消息,但只有在存档中的所有对象都已加载并初始化之后。当对象接收到awakeFromNib
消息时,它的所有outlet
和action
连接都已建立。
您必须调用awakeFromNib
的超实现,以使父类有机会执行它们所需的任何额外初始化。尽管这个方法的默认实现什么都不做,许多UIKit类提供非空实现。您可以在自己的awakeFromNib
方法期间的任何时候调用超级实现。
请注意
在接口生成器的测试模式期间,此消息还被发送到从已加载的接口生成器插件实例化的对象。因为插件链接到包含对象定义代码的框架,所以Interface Builder
能够在出现时调用它们的awakeFromNib
方法。对于为Xcode
项目创建的自定义对象则不是这样。接口生成器只知道那些对象的定义的输出口和操作;它不能访问它们的实际代码。
在实例化过程中,归档中的每个对象都是未存档的,然后使用适合其类型的方法初始化。符合NSCoding
协议的对象(包括UIView
和UIViewController
的所有子类)使用initWithCoder:
方法初始化。所有不符合NSCoding
协议的对象都使用它们的init
方法进行初始化。在实例化和初始化所有对象之后,加载nib
的代码将为所有这些对象重新建立outlet
和action
连接。然后调用对象的awakeFromNib
方法。有关加载Nib
过程中所遵循的步骤的详细信息,请参见资源编程指南中的Nib
文件。
重要的
因为不能保证从归档文件实例化对象的顺序,所以初始化方法不应该向层次结构中的其他对象发送消息。可以在awakeFromNib
方法中安全地向其他对象发送消息。
通常,对于需要额外设置而在设计时无法完成的对象,您可以实现awakeFromNib
。例如,您可以使用此方法自定义任何控件的默认配置,以匹配用户首选项或其他控件中的值。您还可以使用它将各个控件恢复到应用程序的某些先前状态。
- (NSDictionary<NSString *,id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;
返回一个字典,其中包含由给定数组中的每个键标识的属性值。
默认实现调用valueForKey:
对于键中的每个键,用字典中的NSNull
值替换返回的nil
值。
- (void)didChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;
通知观察对象,指定的有序到多关系的索引上发生了指定的更改。
很少需要在子类中重写此方法,但如果需要,请确保调用super
。对该方法的调用总是与对willChange:valuesAtIndexes:forKey:
的匹配调用配对。
- (void)didChangeValueForKey:(NSString *)key;
通知观察对象给定属性的值已更改。
手动实现键值观察器遵从性时,请使用此方法通知被观察对象键值刚刚更改。对该方法的调用总是与对willChangeValueForKey:
的匹配调用配对。
很少需要在子类中重写此方法,但如果需要,请确保调用super
- (void)didChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;
通知观察对象,指定的更改是对指定的无序到多关系进行的。
很少需要在子类中重写此方法,但如果需要,请确保调用super。
- (BOOL)isEqualTo:(id)object;
返回一个布尔值,该值指示接收方是否等于另一个给定对象。
在计算一个NSWhoseSpecifier
对象(该对象包含一个以NSEqualToComparison
为运算符的测试)的过程中,如果潜在指定的对象或被测试的对象都没有实现scriptingIsEqualTo:
方法,则可以向每个潜在指定的对象发送isEqualTo:
消息。
如果发送到相同对象的isEqualTo:
消息将返回YES
,则NSObject
提供的此方法的默认实现将返回YES
。
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
返回一个可变数组代理,该代理提供对由给定键指定的有序到多关系的读写访问。
添加到可变数组中的对象与接收方相关,从可变数组中删除的对象变得无关。默认实现将相同的简单访问器方法和数组访问器方法识别为valueForKey:
,并遵循相同的直接实例变量访问策略,但总是返回一个可变集合代理对象,而不是valueForKey:
将返回的不可变集合。
mutableArrayValueForKey:
使用的搜索模式在键值编码编程指南中的访问器搜索模式中进行了描述。
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
返回一个可变数组,该数组提供对给定键路径指定的有序到多关系的读写访问。
- (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key;
返回一个可变的有序集,该集提供对由给定键指定的惟一有序多关系的读写访问。
添加到可变集代理的对象与接收方相关,从可变集删除的对象与接收方无关。默认实现将相同的简单访问器方法和设置访问器方法识别为valueForKey:
,并遵循相同的直接实例变量访问策略,但总是返回一个可变集合代理对象,而不是valueForKey:
将返回的不可变集合。
mutableOrderedSetValueForKey:
使用的搜索模式在键值编码编程指南中的访问器搜索模式中进行了描述。
- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath;
一个可变的有序集,提供对keyPath指定的惟一到多关系的读写访问。
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
返回一个可变的set代理,该代理提供对由给定键指定的无序到多关系的读写访问。
添加到可变集代理的对象与接收方相关,从可变集删除的对象与接收方无关。默认实现将相同的简单访问器方法和设置访问器方法识别为valueForKey:
,并遵循相同的直接实例变量访问策略,但总是返回一个可变集合代理对象,而不是valueForKey:
将返回的不可变集合。
mutableSetValueForKey:
使用的搜索模式在键值编码编程指南中的访问器搜索模式中进行了描述。
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context;
在给定上下文的情况下,阻止观察者对象接收相对于接收此消息的对象的键路径指定的属性的更改通知。
对于以前没有注册为观察者的对象,调用removeObserver:forKeyPath:
是一个错误。
确保在释放addObserver:forKeyPath:options:context:
中指定的任何对象之前调用此方法(或removeObserver:forKeyPath:context:
)。
- (void)setNilValueForKey:(NSString *)key;
子类可以重写此方法以其他方式处理请求,例如用0
或前哨值替换nil
并再次调用setValue:forKey:
或直接设置变量。默认实现引发一个NSInvalidArgumentException
。
- (void)setValue:(id)value forKey:(NSString *)key;
将给定键指定的接收器的属性设置为给定值。
如果键标识了一对一的关系,则将由值指定的对象关联到接收方,如果存在相关对象,则将其解除关联。给定一个集合对象和一个标识一对多关系的键,将集合中包含的对象与接收者关联起来,如果存在先前相关的对象,则不关联它们。
setValue:forKey:
使用的搜索模式在键值编码编程指南中的访问器搜索模式中进行了描述。
在引用计数的环境中,如果直接访问实例变量,则保留值。
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
将由给定键路径标识的属性的值设置为给定值。
该方法的默认实现使用valueForKey:
获取每个关系的目标对象,并向最终对象发送setValue:forKey:
消息。
当使用此方法且目标对象不实现该值的访问器时,默认行为是该对象保留值,而不是复制或分配值。
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
由setValue:forKey
调用:当它没有找到给定键的属性时。
子类可以重写此方法以其他方式处理请求。默认实现会引发NSUndefinedKeyException
。
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues;
使用给定字典中的值设置接收方的属性,使用其键来标识属性。
默认实现为每个键-值对调用setValue:forKey:
,用nil
替换keyedValues
中的NSNull
值。
- (BOOL)validateValue:(inout id _Nullable *)ioValue forKey:(NSString *)inKey error:(out NSError * _Nullable *)outError;
- (BOOL)validateValue:(inout id _Nullable *)ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError * _Nullable *)outError;
如果ioValue
指向的值对inKey
标识的属性有效,或者该方法能够修改ioValue
的值使其有效,则布尔值设置为YES;否则没有。
此方法的默认实现在接收方的类中搜索一个验证方法,该验证方法的名称与validate<Key>:error:
匹配。如果您为属性定义了这样一个方法,那么validateValue:forKey:error:
的默认实现在被要求验证相应的属性时调用它,允许您的方法在需要时更改输入值,并确定返回值。
如果对于特定的属性不存在这样的方法,validateValue:forKey:error:
返回YES。换句话说,默认情况下,如果不显式地为给定的属性提供验证方法,常规验证调用将成功。
- (id)valueForKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForUndefinedKey:(NSString *)key; // 子类可以重写此方法以返回未定义键的替代值。默认实现会引发NSUndefinedKeyException。
valueForKey:
用于查找要返回的正确值的搜索模式在键值编码编程指南中的访问器搜索模式中进行了描述。
- (void)willChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;
通知观察对象,指定的更改将在指定的有序到多关系的给定索引处执行。
手动实现键值观察遵从性时使用此方法。
重要的
更改值之后,必须使用相同的参数调用相应的didChange:valuesAtIndexes:forKey:
。
- (void)willChangeValueForKey:(NSString *)key;
通知观察对象给定属性的值即将更改。
手动实现键值观察器遵从性时,请使用此方法通知被观察对象key的值即将更改。
这个方法的更改类型是NSKeyValueChangeSetting
。
重要的
更改值之后,必须使用相同的参数调用相应的didChangeValueForKey:
。
- (void)willChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;
通知观察对象,指定的更改将对指定的无序到多关系进行。
重要的
更改值之后,必须使用相同的参数调用相应的didChangeValueForKey:withSetMutation:usingObjects:
。
Type Methods
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;
返回一个布尔值,该值指示所观察的对象是否支持对给定键的键值自动观察。
如果键值观察机制应该自动调用willChangeValueForKey:/didChangeValueForKey:
和willChange:valuesAtIndexes: /didChange:valuesAtIndexes:forKey:
当类的实例接收到键值编码消息时,或者调用与键值编码兼容的方法时,则为YES;否则没有。
默认实现返回YES。从OS X 10.5开始,该方法的默认实现在接收类中搜索名称与<Key>的模式+automaticallyNotifiesObserversOf
匹配的方法,如果找到该方法,则返回调用该方法的结果。任何找到的方法都必须返回BOOL。如果没有找到这样的方法,则返回YES。
+ (NSString *)debugDescription;
调试描述
+ (NSUInteger)hash;
哈希值
+ (NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key;
为其值影响指定键值的属性返回一组键路径。
当键的观察者注册到接收类的实例中时,观察自身的键值会自动观察同一个实例的所有键路径,并在这些键路径的值发生变化时向观察者发送键的更改通知。
该方法的默认实现在接收类中搜索名称与影响<Key>
的模式+ keypathsforvaluesaffect
匹配的方法,如果找到该方法,则返回调用该方法的结果。任何这样的方法都必须返回NSSet
。如果没有找到这样的方法,则会返回一个NSSet
,该NSSet
是根据以前对已弃用的setKeys:triggerChangeNotificationsForDependentKey:
方法的调用所提供的信息计算的,以实现向后二进制兼容性。
当属性的getter
方法使用其他属性的值计算要返回的值时,您可以覆盖此方法,这些属性包括按键路径定位的属性的值。您的覆盖通常应该调用super
并返回一个集合,该集合中包含这样做所产生的任何成员(以便不干扰超类中该方法的覆盖)。
请注意
当您使用类别向现有类别添加计算属性时,请不要重写此方法,类别中的重写方法不受支持。在这种情况下,实现一个匹配的+ keypathsforvaluesaffect <Key>
来利用这种机制。
网友评论