a brief summary of 1:ios SEL
SEL is a wrapper for the method. Package SEL Type data it corresponds to the corresponding method address, find the method address to call the method
A. Where to store the method
The methods of each class in memory are stored in the class object
Each method has a corresponding sel type of data
the corresponding method address can be found based on a SEL data, which in turn calls the method
definition of SEL type: typedef struct OBJC_SELECTOR *sel
creation of B.sel objects
SEL S1 = @selector (test1); // Wrap the Test1 method into a Sel object
SEL s2 = nsselectorfromstring (@ "test1"); // Convert a string method to a Sel object
Other uses of the C.sel object
Convert a Sel object to a NSString object
NSString *str = Nsstringfromselector (@selector (test));
Instance:
Person *p = [person new];//call Object P's test method [P Performselector: @selector (test)]; [Person Performselector: @selector (test2:) withobject:@ "incoming parameters"];
Person Class Code: #import "Person.h" @implementation person-(void) test{ NSLog (@ "parameterless object method");} -(void) Test2: (NSString *) str{ NSLog (@ "method%@ with Parameters", str);} @end
D: the use of arrays
Executes the test method once for each element of an array of arrays [array makeobjectsperformselector: @selector (test)]; [Array makeobjectsperformselector: @selector (test) withobject:@ "AAA"];//to sort an array of arrays [array Sortedarrayusingselector: @selector (compare:)];
E: About SEL application (target-action design mode)
In the button we often use the following event to add code:
-(void) AddTarget: (nullable ID) Target action: (SEL) Action forcontrolevents: (uicontrolevents) controlevents;
Instance:
#import <UIKit/UIKit.h> @interface tapview:uiview//target @property (weak,nonatomic) ID target;//behavior @property (assign , nonatomic) SEL action;//custom Method-(void) Addcustomtarget: (ID) Target andaction: (SEL) action; @end
#import "TapView.h" @implementation tapview//custom Method-(void) Addcustomtarget: (ID) Target andaction: (SEL) action{ _ action = action; _target = target;} -(void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (uievent *) event{ //When the view is clicked, Target executes the action method and passes itself over. First the agent cannot be empty, and the proxy (agent is the object!) There are methods in the class and can be sent out. if (nil! = _target && [[_target class] instancesrespondtoselector:_action]) { [_target performselector:_ Action withobject:self];} }
Another example:
#import <Foundation/Foundation.h> #import <objc/runtime.h> #import "Debug.h"//not given; Just an assert@interface nsobject (Extras)//enforce the rule that the selector used must return void.-(void) performvoid Returnselector: (SEL) Aselector Withobject: (ID) object;-(void) Performvoidreturnselector: (SEL) aselector;@ End@implementation NSObject (Extras)//Apparently the reason the regular performselect gives a compile time warning is tha t the system doesn ' t know the return type. I ' m going to (a) Make sure that the return type was void, and (b) Disable this warning//see Http://stackoverflow.com/quest ions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown-(void) CheckSelector: (SEL) Aselector {//See http://stackoverflow.com/questions/14602854/ Objective-c-is-there-a-way-to-check-a-selector-return-value Method m = Class_getinstancemethod ([Self class], Aselector); Char type[128]; Method_getreturntype (m, type, sizeof (type)); NSString *message = [[NSString Alloc] initwithformat:@ "Nsobject+extras.performvoidreturnselector:%@.%@ selector (type:%s)", [Self class], Nsstringfromselector (Aselector), type]; NSLog (@ "%@", message); if (type[0]! = ' V ') {message = [[NSString alloc] initwithformat:@ "%@ is not void", message]; [Debug Asserttrue:false withmessage:message]; }}-(void) Performvoidreturnselector: (SEL) Aselector withobject: (ID) object {[self checkselector:aselector]; #pragma Clang diagnostic push#pragma clang diagnostic ignored "-warc-performselector-leaks"//Since the selector (aselector) I s returning void, it doesn ' t make sense to try to obtain the return result of Performselector. In fact, if we do, it crashes the app. [Self performselector:aselector withobject:object]; #pragma clang diagnostic pop}-(void) Performvoidreturnselector: ( SEL) Aselector {[self checkselector:aselector]; #pragma clang diagnostic push#pragma clang diagnostic ignored "-warc-per Formselector-leaks "[Self perfoRmselector:aselector]; #pragma clang diagnostic pop} @end
2: Proxy Mode instance
#import <UIKit/UIKit.h> @protocol touchviewdelegate <nsobject>-(void) Changeviewcolor: (Uicolor *) color;@ End@interface touchview:uiview//declares an agent, this agent complies with Touchviewdelegate protocol, @property (nonatomic,assign) id< Touchviewdelegate> delegate; @end
#import "TouchView.h" @implementation touchview//we still use touchesbegandian-(void) Touchesbegan: (Nsset<uitouch *> * ) Touches withevent: (uievent *) event{ if (nil! = self.delegate && [self.delegate respondstoselector:@ Selector (changeviewcolor:)]) { //We send a color to our viewcontroller. [Self.delegate Changeviewcolor:[uicolor Browncolor]; }} @end
Application code: #import "ViewController.h" #import "TouchView.h"//here Viewcontroller to abide by the agreement .... @interface Viewcontroller () < Touchviewdelegate> @property (Nonatomic,strong) TouchView *touchview; @end @implementation viewcontroller-(void) viewdidload { [super viewdidload]; Self.touchview = [[TouchView alloc]initwithframe:cgrectmake (+, +, +)]; Self.touchView.backgroundColor = [Uicolor redcolor]; Specifies that the agent for TouchView is Viewcontroller. That is , itself ~ self.touchView.delegate =self; [Self.view AddSubview:self.touchView];} -(void) Changeviewcolor: (Uicolor *) color{ //Now the parameter color is a value because it was passed over the Touchview page. Self.touchView.backgroundColor = color;} @end
3: about Bolck application
#import <uikit/uikit.h>//renaming block myblocktypedef Void (^myblock) (NSString *); @interface Otherviewcontroller: UIVIEWCONTROLLER//ARC: Semantic settings use strong to @property (Nonatomic,strong) Myblock block; @end
#import "OtherViewController.h" @interface Otherviewcontroller () @property (Nonatomic,strong) Uitextfield *textfield; @end @implementation otherviewcontroller-(void) viewdidload { [super viewdidload]; Self.textfield = [[Uitextfield alloc]initwithframe:cgrectmake (0, 414, +)]; Self.textField.backgroundColor = [Uicolor lightgraycolor]; Self.view.backgroundColor = [Uicolor whitecolor]; [Self.view AddSubview:self.textField];} -(void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (uievent *) event{ self.block (_textfield.text); [Self.navigationcontroller Popviewcontrolleranimated:yes];} @end
Application code: otherviewcontroller *OTHERVC = [[Otherviewcontroller alloc]init]; __weak typeof (self) weak = self; Assign a value to block ~ Othervc.block = ^ (NSString *string) { weak.label.text = string; }; [Self.navigationcontroller PUSHVIEWCONTROLLER:OTHERVC Animated:yes];
several triggering methods of 4:uibutton
A, Uicontroleventtouchdown
The left mouse button press (note: just "Press ") the action
b, Uicontroleventtouchdownrepeat
The left mouse button repeatedly pressed (note: just "Press ") of the action, for example, the mouse double-click, three-hit,..., multiple combos.
Note: When repeatedly pressed, the sequence of events is this:
Uicontroleventtouchdown
(UIControlEventTouchUpInside)
Uicontroleventtouchdown
Uicontroleventtouchdownrepeat
(UIControlEventTouchUpInside)
Uicontroleventtouchdown
Uicontroleventtouchdownrepeat
(UIControlEventTouchUpInside)
......
In addition to the first press, a Uicontroleventtouchdown event is followed every time, followed by a uicontroleventtouchdownrepeat event.
C ,uicontroleventtouchdraginside
Refers to pressing the mouse and then dragging within the bounds of the control.
D ,uicontroleventtouchdragoutside
Unlike uicontroleventtouchdraginside , when you drag, the mouse is outside the bounds of the control.
But first there has to be a uicontroleventtouchdown event, then a uicontroleventtouchdraginside event, followed by a Uicontroleventtouchdragexit event, at this point, the mouse is already outside the control, continue to drag is the uicontroleventtouchdragoutside event.
To do this, press the mouse inside the control, and then drag outside the control.
e ,uicontroleventtouchdragenter
Refers to the event that occurs when a drag action, from outside the bounds of the control, is inside.
F ,uicontroleventtouchdragexit
Refers to an event that occurs when a drag action, from within the bounds of a control, occurs outside.
g ,uicontroleventtouchupinside
Refers to the mouse raised within the scope of the control, the premise is to press, that is, uicontroleventtouchdown or uicontroleventtouchdownrepeat event.
h ,uicontroleventtouchupoutside
Indicates that the mouse is lifted outside the bounds of the control, before it is pressed and then dragged outside the control, i.e.
Uicontroleventtouchdown
uicontroleventtouchdraginside (n )
Uicontroleventtouchdragexit
uicontroleventtouchdragoutside (n )
Time series, and then just lift up the mouse to generate the uicontroleventtouchupoutside event.
5: Let the compiler shut up on some warnings
A: Method deprecation alarm
#pragma clang diagnostic push #pragma clang diagnostic ignored "-wdeprecated-declarations" //The method of warning, such as SEL [ TestFlight Setdeviceidentifier:[[uidevice Currentdevice] uniqueidentifier]; #pragma clang diagnostic pop
B: No variables used
#pragma clang diagnostic push #pragma clang diagnostic ignored "-wunused-variable" int A;
6: A hexagon, and only in the hexagon has a click effect
#import <uikit/uikit.h>//hexagon button@interface hexagonbutton:uiviewns_assume_nonnull_begintypedef void (^ Hexagonbuttonblock) (); @property (nonatomic, strong) Uibezierpath *path; @property (nonatomic, strong) Cashapelayer * Masklayer; @property (nonatomic, Strong) Hexagonbuttonblock block; Click events//Add Click events ns_assume_nonnull_end@end
#import "HexagonButton.h" @implementation hexagonbutton-(Instancetype) initWithFrame: (CGRect) frame{if ([super Initwithframe:frame]) {self.backgroundcolor = [uicolor Browncolor]; self.userinteractionenabled = YES; Add a click gesture UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initwithtarget:self action: @selector (click: )]; [Self addgesturerecognizer:tap]; } return self;} -(void) layoutsubviews{[Super Layoutsubviews]; CGFloat SIZE = self.frame.size.width; Step 1: Generate hexagon path CGFloat longside = SIZE * 0.5 * COSF (M_PI * 30/180); CGFloat shortside = SIZE * 0.5 * sin (M_PI * 30/180); CGFloat k = SIZE * 0.5-longside; The whole path is moved down to ensure that the hexagon path is in the middle of the graph _path = [Uibezierpath Bezierpath]; [_path movetopoint:cgpointmake (0, Longside + k)]; [_path Addlinetopoint:cgpointmake (shortside, + K)]; [_path addlinetopoint:cgpointmake (shortside + shortside + shortside, K)]; [_path Addlinetopoint:cgpointmake(SIZE, Longside + k)]; [_path addlinetopoint:cgpointmake (Shortside * 3, Longside * 2 + k)]; [_path Addlinetopoint:cgpointmake (Shortside, Longside * 2 + k)]; [_path Closepath]; Step 2: Create a mask based on the path _masklayer = [Cashapelayer layer]; _masklayer.position = Self.center; _masklayer.path = [_path Cgpath]; Step 3: Add mask self.layer.mask = _masklayer; Self.backgroundcolor = [Uicolor orangecolor];} Click Event-(void) Click: (UITapGestureRecognizer *) tap{if (_block) {_block (); }}-(UIView *) HitTest: (cgpoint) point withevent: (Uievent *) Event {//if the clicked area is within the path created by the IF (Cgpathcontainspoint (_path). Cgpath, NULL, point, NO) {return [Super Hittest:point withevent:event]; } return nil;} @end
Create six warp button Hexagonbutton * Hexagonbutton = [[Hexagonbutton alloc] Initwithframe:cgrectmake (+,-+, +)]; Hexagonbutton.center = Self.view.center; Hexagonbutton.block = ^ () { NSLog (@ "Hexagon area is clicked"); }; [Self.view Addsubview:hexagonbutton];
7:self.navigationcontroller.viewcontrollers modification
var Controllerarr = Self.navigationcontroller?. viewcontrollers//get controller array Controllerarr?. RemoveAll ()//Remove historical path saved in Controllerarr //re-add New path Controllerarr?. Append (Self.navigationcontroller?). Viewcontrollers[0]) Controllerarr?. Append (C) Controllerarr? Append (b) ///At this point the historical path is (root-c-B) //The new jump path will be formed Set into Self.navigationcontroller Self.navigationcontroller? Setviewcontrollers (controllerarr!, animated:true)//Direct write, complete the Jump B page while modifying the previous jump path
The main solution to those chaotic turn, not in order to the problem;
iOS Development Basics-Fragmentation 45