1. What is the difference between using the weak keyword and comparing assign?
2. How do I use the Copy keyword?
3. What is the problem with this notation: @property (copy) Nsmutablearray *array;
4. How do I make my own class use the copy modifier? How do I rewrite the setter with the Copy keyword?
What is the nature of [email protected]? How Ivar, Getter, setter are generated and added to this class
How to use @property in [email protected] and category
7.runtime How to implement weak properties
What are the property keywords in [email protected]? /@property What modifiers can be followed?
Does 9.weak attribute need to be nil in dealloc?
[email protected] and @dynamic respectively what role?
11.ARC, what are the default keywords when no attribute keywords are explicitly specified?
12. The NSString (or nsarray,nsdictionary) declared with @property often uses 13.copy keywords, why? If you use the strong keyword, what might be causing the problem?
14. Copy operations on non-collection class objects
15 copy and Mutablecopy of a collection class object
[email protected] What are the rules for synthetic instance variables? If the property is named Foo and there is an instance variable named _foo, will the new variable be automatically synthesized?
17. After you have the auto-synthetic attribute instance variable, what other usage scenarios do @synthesize have?
What happens when a message is sent to a nil object in 18.OBJC?
What is the relationship between sending a message to an object in 19.OBJC [obj foo] and the Objc_msgsend () function?
20. When will the unrecognized selector abnormal be reported?
21. How does a OBJC object perform memory layout? (Consider the case of a parent class)
22. What does the pointer to ISA for an OBJC object point to? What's the effect?
23. What does the following code output?
@implementation Son:father
-(ID) init
{
self = [super init];
if (self) {
NSLog (@ "%@", Nsstringfromclass ([Self class]));
NSLog (@ "%@", Nsstringfromclass ([Super class]));
}
return self;
}
@end
What does the 24._objc_msgforward function do, and what happens when you call it directly?
25.runtime How to implement weak variable auto-nil?
26. Can I add an instance variable to a compiled class? Can I add an instance variable to a class that is created at run time? Why?
What is the relationship between 27.runloop and threads?
What is the mode function of 28.runloop?
29. With + Scheduledtimerwithtimeinterval ... The way the timer triggers the list on the sliding page, the timer will tentative callback, why? How to solve?
30. Guess how the interior of Runloop is implemented?
What mechanism does 31.OBJC use to manage object memory?
32.ARC How do I help developers manage their memory?
33. What time does a Autorealese object release without manually specifying Autoreleasepool? (for example, created in a VC viewdidload)
Under what circumstances does the 34.bad_access appear?
35. How does Apple achieve autoreleasepool?
36. What happens when a block is used and how is the reference loop resolved?
37. How do I modify the block external variables within a block?
38. Do you also consider reference loops when using some of the system's block APIs, such as the block version of UIView?
What are the two types of queues (dispatch_queue_t) for 39.GCD?
40. How can I synchronize several asynchronous calls with GCD? (such as loading multiple pictures asynchronously based on several URLs, and then compositing an entire image after the download is complete)
What is the role of 41.dispatch_barrier_async?
42. Why did Apple abandon dispatch_get_current_queue?
43. How does the following code work?
-(void) viewdidload
{
[Super Viewdidload];
NSLog (@ "1");
Dispatch_sync (Dispatch_get_main_queue (), ^{
NSLog (@ "2");
});
NSLog (@ "3");
}
44.addobserver:forkeypath:options:context: What are the roles of each parameter, and which method do you need to implement in observer to get the KVO callback?
45. How to manually trigger a value of KVO
46. If a class has an instance variable NSString *_foo, call Setvalue:forkey: Can I use Foo or _foo as key?
How does the set operator in the 47.KVC keypath work?
48.KVC and Kvo's keypath must be a property?
49. How can I close the default implementation of the default KVO and enter the custom KVO implementation?
50.apple in what way to achieve the kvo of an object?
Why can the 51.IBOutlet view properties be set to weak?
How to use the user Defined Runtime attributes in 52.IB?
53. How to debug Bad_access errors
54.LLDB (GDB) Common debug commands?
26. Can I add an instance variable to a compiled class? Can I add an instance variable to a class that is created at run time? Why?
The instance variable cannot be added to the compiled class;
The ability to add instance variables to classes created at run time;
Explained below:
Since the compiled class is already registered in runtime, the memory size of the list and Instance_size instance variables of the Objc_ivar_list instance variable in the class structure has been determined, and the runtime calls Class_setivarlayout or CL Ass_setweakivarlayout to handle strong weak references. Therefore, you cannot add an instance variable to a class that exists;
The runtime creates a class that can add an instance variable, calling the Class_addivar function. But after calling Objc_allocateclasspair, the reason is Objc_registerclasspair before.
What is the relationship between 27.runloop and threads?
In general, the run loop, like its name, loops represents a loop that, together with run, represents a loop that has been running. In fact, the run loop and the thread are tightly connected, so you can say that the run loop is meant for threading and without threads, it doesn't have to exist. Run loops is the infrastructure part of the thread, and both Cocoa and corefundation provide the run loop object to facilitate configuration and management of the thread's run loop (Cocoa, for example). Each thread, including the main thread of the program, has a corresponding run loop object.
Runloop and threading Relationships:
The run loop of the main thread is started by default.
iOS app, the program starts with a main () function like this
int main (int argc, char * argv[]) {
@autoreleasepool {
Return Uiapplicationmain (argc, argv, Nil, Nsstringfromclass ([Appdelegate class]));
}
}
The focus is on the Uiapplicationmain () function, which sets a Nsrunloop object for the main thread, which explains why our app can take a break when no one is working and then respond immediately when it needs to be done.
For other threads, the run loop is not started by default, and if you need more thread interaction you can manually configure and start it if the thread is simply going to perform a long, determined task.
In any thread of the COCOA program, the following code can be used to get the run loop to the current thread.
Nsrunloop *runloop = [Nsrunloop currentrunloop];
Reference link: "Objective-c run Loop detailed".
What is the mode function of 28.runloop?
The model is primarily used to specify the priority of an event in a running loop, divided into:
Nsdefaultrunloopmode (Kcfrunloopdefaultmode): Default, Idle state
Uitrackingrunloopmode:scrollview when sliding
Uiinitializationrunloopmode: At startup
Nsrunloopcommonmodes (kcfrunloopcommonmodes): Mode collection
There are two publicly available Mode in Apple:
Nsdefaultrunloopmode (Kcfrunloopdefaultmode)
Nsrunloopcommonmodes (Kcfrunloopcommonmodes)
29. With + Scheduledtimerwithtimeinterval ... The way the timer triggers the list on the sliding page, the timer will tentative callback, why? How to solve?
Runloop can only be run in a mode, if you want to change mode, the current loop also needs to stop restarting to new. Using this mechanism, The mode of Nsdefaultrunloopmode (Kcfrunloopdefaultmode) in the ScrollView scrolling process switches to uitrackingrunloopmode to ensure smooth sliding of scrollview: only in Nsdefaultru Events handled in Nloopmode mode can affect the sliding of scrollview.
If we add a Nstimer object to the main run loop with Nsdefaultrunloopmode (Kcfrunloopdefaultmode), the ScrollView will be switched during the scrolling process because of mode. The Nstimer will no longer be dispatched.
Also, because mode is customizable, you can:
The question of how the timer will be affected by the ScrollView slide can be resolved by adding the timer to Nsrunloopcommonmodes (kcfrunloopcommonmodes). The code is as follows:
//
http://weibo.com/luohanchenyilong/(Weibo @ios program dogs Yuan)
Https://github.com/ChenYilong
Add a timer to the Nsdefaultrunloopmode
[Nstimer scheduledtimerwithtimeinterval:1.0
Target:self
Selector: @selector (Timertick:)
Userinfo:nil
Repeats:yes];
And then add it to nsrunloopcommonmodes.
Nstimer *timer = [Nstimer timerwithtimeinterval:1.0
Target:self
Selector: @selector (Timertick:)
Userinfo:nil
Repeats:yes];
[[Nsrunloop Currentrunloop] Addtimer:timer formode:nsrunloopcommonmodes];
30. Guess how the interior of Runloop is implemented?
In general, a thread can only perform one task at a time, and the thread exits after execution completes. If we need a mechanism that allows threads to handle events at any time without exiting, the usual code logic is this:
function loop () {
Initialize ();
do {
var message = Get_next_message ();
Process_message (message);
} while (Message! = quit);
}
or use pseudo-code to show the following:
//
http://weibo.com/luohanchenyilong/(Weibo @ios program dogs Yuan)
Https://github.com/ChenYilong
int main (int argc, char * argv[]) {
Program always running state
while (appisrunning) {
Sleep status, waiting for wake-up events
ID whowakesme = Sleepforwakingup ();
Get wake-up events
ID event = GetEvent (whowakesme);
Start processing Events
Handleevent (event);
}
return 0;
}
Reference Links:
"In-depth understanding of Runloop"
From Bowen Cfrunloop, the original author is Weibo @ I'll call sunny.
What mechanism does 31.OBJC use to manage object memory?
The retaincount mechanism is adopted to determine whether an object needs to be freed. Each time Runloop, will check the object's Retaincount, if the Retaincount is 0, indicating that the object has no place to continue to use, can be released.
32.ARC How do I help developers manage their memory?
Compile-time based on the code context, insert Retain/release
ARC is not as simple as adding retain/release/autorelease at compile time relative to MRC. It should be both the compile and run phases to help developers manage memory.
At compile time, ARC uses the lower level C interface implementation of the Retain/release/autorelease, this performance is better, but also why not in the ARC Environment manual retain/release/autorelease, Simultaneously optimizes the paired-retain/release operation of the same object in the same context (that is, ignoring unnecessary actions); Arc also contains run-time components, where optimizations are more complex, but cannot be ignored. "TODO: Subsequent updates will be described in detail below"
33. What time does a Autorealese object release without manually specifying Autoreleasepool? (for example, created in a VC viewdidload)
In two cases: manual intervention to release the opportunity, the system automatically release.
Manual Intervention Release Timing – Specifies that Autoreleasepool is called: Released at the end of the current scope brace.
System Auto-Release – Do not specify Autoreleasepool manually
After the Autorelease object is scoped, it is added to the most recently created auto-release pool and is released at the end of the current runloop iteration.
The timing of the release is summed up and can be used to indicate:
Diagram of Autoreleasepool and Runloop
This diagram is explained in detail below:
From the start of the program to the completion of the load is a complete run cycle, and then will stop, waiting for user interaction, the user each interaction will start a run cycle, to handle all the user's click events, Touch events.
As we all know: All Autorelease objects are automatically added to the recently created auto-release pool after they have been scoped.
But if you put it in the autoreleasepool of the application main.m every time, there will be a moment to fill it up sooner or later. There must be a release action in this process. When?
It is destroyed before a complete run cycle is completed.
What time does it create an auto-free pool? An auto-free pool is created after the event is detected and started by the run loop.
The runloop of a child thread is not working by default and cannot be created proactively, and must be created manually.
Custom nsoperation and Nsthread need to manually create an auto-free pool. For example, the main method in the custom Nsoperation class must add an auto-release pool. Otherwise, when the scope is out, automatically releasing the object causes a memory leak because it does not automatically dispose of the pool.
But for the default operation of Blockoperation and Invocationoperation, the system has been packaged for us, without the need to manually create an auto-release pool.
@autoreleasepool when the auto-free pool is destroyed or exhausted, release messages are sent to all objects in the auto-free pool, freeing all objects in the pool for automatic deallocation.
If a Autorelease object is created in the viewdidload of a VC, the object is destroyed before the Viewdidappear method executes.
Reference link: "Autorelease behind the Curtain"
Under what circumstances does the 34.bad_access appear?
A wild pointer is accessed, such as releasing a release on an already freed object, accessing a member variable that has been disposed of, or sending a message. Dead loop
35. How does Apple achieve autoreleasepool?
The Autoreleasepool is implemented in the form of an array of queues, mainly through the following three functions.
Objc_autoreleasepoolpush
Objc_autoreleasepoolpop
Objc_autorelease
Look at the function name to know, the autorelease respectively to perform push, and pop operation. Performs a release operation when destroying an object.
For example: We all know that objects created with the class method are autorelease, so once the person is scoped, we can see the call stack information when a breakpoint is put in the Dealloc method of the person:
Enter image description here
36. What happens when a block is used and how is the reference loop resolved?
When a block is strongly referenced in an object and the object is strongly referenced in the block, a circular reference is emitted.
The workaround is to use the object with the __weak or __block modifier before it is used in the block.
ID weak weakself = self; or weak __typeof (&*self) weakself = Self The method can set the macro
ID __block weakself = self;
Or force one party to void xxx = nil.
Detect circular reference problems in your code and use one of Facebook's open source detection tools, fbretaincycledetector.
37. How do I modify the block external variables within a block?
By default, external variables that are accessed in the block are copied in the past, that is, the write operation does not take effect on the original variable. But you can add __block to make the write operation work, the sample code is as follows:
__block int a = 0;
void (^foo) (void) = ^{
A = 1;
}
F00 ();
Here, the value of a is modified to 1
Reference link: Weibo @ Tang Qi _boy's book "iOS Development Advanced", 11th. 2.3 Chapters
38. Do you also consider reference loops when using some of the system's block APIs, such as the block version of UIView?
Some of the block APIs in the system do not need to be considered when UIView block versions are animated, but there are some APIs to consider:
The so-called "reference loops" refer to strong references in both directions, so there are no problems with "one-way strong references" (block strongly referencing self), such as these:
[UIView animatewithduration:duration animations:^{[Self.superview layoutifneeded];}];
[[Nsoperationqueue mainqueue] addoperationwithblock:^{self.someproperty = xyz;}];
[[Nsnotificationcenter Defaultcenter] addobserverforname:@ "Somenotification"
Object:nil
Queue:[nsoperationqueue Mainqueue]
usingblock:^ (nsnotification * notification) {
Self.someproperty = xyz; }];
These situations do not need to consider "reference loops".
But if you use some of the parameters may contain Ivar system API, such as GCD, Nsnotificationcenter should be careful: for example, if the GCD internal reference self, and GCD other parameters is Ivar, consider the circular reference:
weak __typeof (self) weakself = self;
Dispatch_group_async (_operationsgroup, _operationsqueue, ^
{
typeof (self) strongself = weakself;
[Strongself dosomething];
[Strongself Dosomethingelse];
} );
Similar to:
weak __typeof (self) weakself = self;
_observer = [[Nsnotificationcenter defaultcenter] addobserverforname:@ "TestKey"
Object:nil
Queue:nil
usingblock:^ (Nsnotification *note) {
typeof (self) strongself = weakself;
[Strongself Dismissmodalviewcontrolleranimated:yes];
}];
Self–> _observer–> block–> Self Obviously this is also a circular reference.
Detect circular reference problems in your code and use one of Facebook's open source detection tools, fbretaincycledetector.
What are the two types of queues (dispatch_queue_t) for 39.GCD?
Serial Queue serial Dispatch queue
Parallel Queue Concurrent Dispatch queue
40. How can I synchronize several asynchronous calls with GCD? (such as loading multiple pictures asynchronously based on several URLs, and then compositing an entire image after the download is complete)
Use the Dispatch group to append block to the global group queue, which, if fully executed, executes the end-processing block in the main Dispatch queue.
dispatch_queue_t queue = Dispatch_get_global_queue (Dispatch_queue_priority_default, 0);
dispatch_group_t group = Dispatch_group_create ();
Dispatch_group_async (group, queue, ^{/ load image 1 /});
Dispatch_group_async (group, queue, ^{/ load Image 2 /});
Dispatch_group_async (group, queue, ^{/ load Image 3 /});
Dispatch_group_notify (Group, Dispatch_get_main_queue (), ^{
Merging pictures
});
What is the role of 41.dispatch_barrier_async?
In a parallel queue, in order to maintain the order of certain tasks, it is necessary to wait for some tasks to complete before proceeding, using barrier to wait for the previous task to complete, avoid the data competition and so on. The Dispatch_barrier_async function waits for an operation that is appended to the concurrent dispatch queue in parallel queue, and then performs the processing that the Dispatch_barrier_async function appends, and so on Dispatch_barrier_async the Concurrent dispatch queue resumes until the execution of the appended processing is completed.
For example: Your company weekend with the group travel, high-speed rest station, the driver said: We all go to the toilet, quick, after the toilet on the high-speed. Oversized public toilets, everyone at the same time, the program ape will soon be over, but the Cheng may be slower, even if you first come back, the driver will not start, the driver will wait for everyone to come back before the departure. The addition of the Dispatch_barrier_async function is like the "high speed on the toilet" action.
(Note: Using Dispatch_barrier_async, this function can only be used with custom parallel queues dispatch_queue_t.) Cannot use: Dispatch_get_global_queue, otherwise the role of Dispatch_barrier_async will be the same as the role of Dispatch_async. )
42. Why did Apple abandon dispatch_get_current_queue?
Dispatch_get_current_queue easy to cause deadlock
43. How does the following code work?
- (void) Viewdidload
{
[Super Viewdidload];
NSLog (@ "1");
Dispatch_sync (Dispatch_get_main_queue (), ^{
NSLog (@ "2");
});
NSLog (@ "3");
}
Output only: 1. Occurs when the main thread locks dead.
44.addobserver:forkeypath:options:context: What are the roles of each parameter, and which method do you need to implement in observer to get the KVO callback?
Add key value Observation
/*
1 Observer, the object responsible for handling listener events
2 Properties of observations
3 Options to observe
4 context
*/
[Self.person addobserver:self forkeypath:@ "name" Options:nskeyvalueobservingoptionnew | Nskeyvalueobservingoptionold context:@ "Person Name"];
Observer need to implement the method:
This method will be called by all Kvo to hear the event
/*
1. Properties of observations
2. Objects of observation
3. Change attribute dictionary (new/old)
4. Context, consistent with the time of the listener
*/
-(void) Observevalueforkeypath: (NSString ) KeyPath ofobject: (ID) object change: (nsdictionary ) Change context :(void *) context;
45. How to manually trigger a value of KVO
The so-called "manual trigger" is different from "Auto Trigger":
Automatic triggering refers to a scenario like this: set an initial value before registering KVO, and after registering, set a different value to trigger.
To know how to trigger manually, you must know the principle of automatically triggering KVO:
The key value observation notification relies on the two methods of NSObject: Willchangevalueforkey: and Didchangevlueforkey:. Before a observed property changes, Willchangevalueforkey: It will be called, which will record the old value. And when the change happens, ObserveValueForKey:ofObject:change:context: it will be called, and then Didchangevalueforkey: it will be called. If you can implement these calls manually, you can implement a "manual trigger".
So what is the "manual trigger" usage scenario? In general, we do this only when we want to be able to control the call timing of callbacks.
The following are the specific practices:
If this value is a self.now of time, then the code is as follows: The last two lines of code are indispensable.
The relevant code has been placed in the warehouse.
. m file
Created by Https://github.com/ChenYilong
Weibo @ios Program Dogs Yuan (http://weibo.com/luohanchenyilong/).
The kvo of the value is triggered manually, and the last two lines of code are integral.
@property (nonatomic, strong) NSDate *now;
-(void) Viewdidload {
[Super Viewdidload];
_now = [NSDate Date];
[Self addobserver:self forkeypath:@ ' now ' options:nskeyvalueobservingoptionnew Context:nil];
NSLog (@ "1");
[Self willchangevalueforkey:@ ' now ']; "Manual triggering of Self.now Kvo", must be written.
NSLog (@ "2");
[Self didchangevalueforkey:@ ' now ']; "Manual triggering of Self.now Kvo", must be written.
NSLog (@ "4");
}
But usually we do not do so, we are waiting for the system to "automatically trigger". The implementation principle of "auto trigger":
For example, when calling Setnow: The system will somehow insert Wilchangevalueforkey in the middle:, Didchangevalueforkey: and ObserveValueForKeyPath:ofObject:change: Context: the call.
You might think this is because Setnow: it's a synthetic method, and sometimes we can see someone writing code like this:
- (void) Setnow: (NSDate *) adate {
[Self willchangevalueforkey:@ ' now ']; No need
_now = adate;
[Self didchangevalueforkey:@ ' now '];//no need
}
This is completely unnecessary, do not do so, the KVO code will be called two times. Kvo always calls Willchangevalueforkey before calling the access method:, and then always calls Didchangevalueforkey:. How do you do that? The answer is through the ISA Mix (isa-swizzling). How does Apple implement the KVO of an object in the following way? "will be detailed.
Reference link: Manual change notification-apple official documentation
46. If a class has an instance variable NSString *_foo, call Setvalue:forkey: Can I use Foo or _foo as key?
All can.
How does the set operator in the 47.KVC keypath work?
Must be used on a collection object or on a collection property of a normal object
Simple set operators are @avg, @count, @max, @min, @sum,
Format @ "@sum. Age" or @ "collection properties [email protected]"
48.KVC and Kvo's keypath must be a property?
KVO Supporting instance variables
49. How can I close the default implementation of the default KVO and enter the custom KVO implementation?
Please refer to:
"How to achieve KVO by yourself"
KVO for manually implemented properties
50.apple in what way to achieve the kvo of an object?
Apple's documentation describes the KVO implementation:
Automatic Key-value Observing is implemented using a technique called isa-swizzling ... When a observer is registered for a attribute of an object the ISA pointer of the observed object is modified, pointing To a intermediate class rather than at the true class ...
As you can see from Apple's documentation, Apple doesn't want to expose KVO's implementation details too much. However, if you dig deeper with the method provided by the runtime, all the hidden details will be true:
When you look at an object, a new class is created dynamically. This class inherits from the original class of the object and overrides the setter method of the observed property. The overridden setter method is responsible for notifying all observed objects before and after calling the original setter method: Value changes. Finally, the ISA pointer of this object (the ISA pointer tells the Runtime system what the object's class is) is pointing to the newly created subclass through ISA Mix (isa-swizzling), and the object magically becomes an instance of the newly created subclass. I drew a picture as follows:
Enter image description here
KVO does have a bit of dark magic:
Apple uses Isa mixed write (isa-swizzling) to implement KVO.
Here is a detailed explanation:
The key value observation notification relies on the two methods of NSObject: Willchangevalueforkey: and Didchangevlueforkey:. Before a observed property changes, Willchangevalueforkey: It will be called, which will record the old value. And when the change happens, ObserveValueForKey:ofObject:change:context: it will be called, and then Didchangevalueforkey: it will be called. These calls can be implemented manually, but few people do. Generally we do this only when we want to be able to control the timing of the callback call. In most cases, change notifications are called automatically.
For example, when calling Setnow: The system will somehow insert Wilchangevalueforkey in the middle:, Didchangevalueforkey: and ObserveValueForKeyPath:ofObject:change: Context: the call. You might think this is because Setnow: it's a synthetic method, and sometimes we can see someone writing code like this:
(void) Setnow: (NSDate *) adate {
[Self willchangevalueforkey:@ ' now ']; No need
_now = adate;
[Self didchangevalueforkey:@ ' now '];//no need
}
This is completely unnecessary, do not do so, the KVO code will be called two times. Kvo always calls Willchangevalueforkey before calling the access method:, and then always calls Didchangevalueforkey:. How do you do that? The answer is through the ISA Mix (isa-swizzling). The first time you call AddObserver:forKeyPath:options:context: On an object, the framework creates a new KVO subclass of the class and converts the observed object to the object of the new subclass. In this KVO special subclass, Cocoa creates the setter of the observation attribute, which works roughly as follows:
(void) Setnow: (NSDate *) adate {
[Self willchangevalueforkey:@ ' now '];
[Super Setvalue:adate forkey:@ "Now"];
[Self didchangevalueforkey:@ ' now '];
}
This inheritance and method injection is implemented at runtime, not at compile time. That's why it's so important to name it correctly. KVO can do this only if the KVC naming convention is used.
KVO in the implementation of the ISA pointer to this object (the ISA pointer tells the Runtime system what the object's class is) to this newly created subclass, the object magically becomes an instance of the newly created subclass, through ISA Mix (isa-swizzling). This can be verified in Apple's documentation:
Automatic Key-value Observing is implemented using a technique called isa-swizzling ... When a observer is registered for a attribute of an object the ISA pointer of the observed object is modified, pointing To a intermediate class rather than at the true class ...
However, KVO uses the ISA Mix (isa-swizzling) in the implementation, which is really not easy to find: Apple also overrides, overrides, and returns the-class method. Attempt to deceive us: This class has not changed, that is the original class ...
However, suppose that the class object of "object being listened to" is MYClass, sometimes we can see a reference to Nskvonotifying_myclass instead of a reference to MYClass. We have been able to understand that Apple is using ISA mixed write (isa-swizzling). The specific inquiry process can refer to this blog post.
So Wilchangevalueforkey:, Didchangevalueforkey: And ObserveValueForKeyPath:ofObject:change:context: What is the order of execution of these three methods?
Wilchangevalueforkey:, Didchangevalueforkey: Well understood, ObserveValueForKeyPath:ofObject:change:context: When is the timing of execution?
Let's look at an example:
The code has been placed in the warehouse.
(void) Viewdidload {
[Super Viewdidload];
[Self addobserver:self forkeypath:@ ' now ' options:nskeyvalueobservingoptionnew Context:nil];
NSLog (@ "1");
[Self willchangevalueforkey:@ ' now ']; "Manual triggering of Self.now Kvo", must be written.
NSLog (@ "2");
[Self didchangevalueforkey:@ ' now ']; "Manual triggering of Self.now Kvo", must be written.
NSLog (@ "4");
}
(void) Observevalueforkeypath: (NSString ) KeyPath ofobject: (ID) object change: (Nsdictionary
iOS Face question Collection 2