iOS - FAQ 정리(一)
하나.통지하다
통지에 대해 모두가 낯설지 않을 것이다. 이것은 하나의 예로 사건이 발생할 때 일부 대상을 통지하고 우리가 낮은 정도의 결합 상황에서 통신의 목적을 달성하도록 허용하는 것이다.
알림의 이점: 1.코드를 너무 많이 작성하지 않아도 비교적 간단하게 실현할 수 있다.하나의 통지에 대해 여러 대상이 반응할 수 있다. 즉, 통지는 일대다의 형식이라는 것이다
알림의 단점: 1.컴파일링 기간에 알림이 관찰자가 정확하게 처리할 수 있는지 확인하지 않습니다.등록된 객체를 해제하려면 공지 센터에서 등록을 취소해야 합니다. 3.디버그 응용 프로그램에서 추적하기 어렵다 4.통지를 보낸 후 관찰자로부터 어떠한 피드백 정보도 얻을 수 없다
알림의 기본 구현:
- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:@"test" object:nil];
    NSLog(@"  - %@",[NSThread currentThread]);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil];
    NSLog(@"  - %@",[NSThread currentThread]);
}
- (void)test {
    NSLog(@"  - %@",[NSThread currentThread]);
    sleep(3);
}
 인쇄 결과:
2017-06-13 16:53:01.040  [24531:3283934]   - {number = 1, name = main}
2017-06-13 16:53:10.334  [24531:3283934]   - {number = 1, name = main}
2017-06-13 16:53:13.335  [24531:3283934]   - {number = 1, name = main}
   인쇄 결과 주의: 테스트 방법이 실행된 후에야 완료된 로그를 출력할 수 있습니다.
하위 스레드에서 알림을 보내는 경우
- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:@"test" object:nil];
    NSLog(@"  - %@",[NSThread currentThread]);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        
        NSNotification *notification = [NSNotification notificationWithName:@"test"
                                                                     object:nil];
        // NSPostASAP   NSPostNow
        [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostNow];
        NSLog(@"  - %@",[NSThread currentThread]);
        });
}
- (void)test {
    NSLog(@"  - %@",[NSThread currentThread]);
    sleep(3);
}
 인쇄 결과:
2017-06-13 17:05:01.133  [25191:3296062]   - {number = 1, name = main}
2017-06-13 17:05:02.423  [25191:3296125]   - {number = 3, name = (null)}
2017-06-13 17:05:05.523  [25191:3296125]   - {number = 3, name = (null)}
   결론: 알림을 받는 라인은 알림을 보내는 라인과 같다. 만약에 실제 개발 과정에서 우리는 하위 라인에서 알림을 보낸다. 알림을 받은 후에 UI를 갱신하는 등 작업을 해야 하며 반드시 메인 라인으로 돌아가야 한다.
- (void)viewDidLoad {
    [super viewDidLoad];
     _observe = [[NSNotificationCenter defaultCenter] addObserverForName:@"test" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
       NSLog(@"  - %@",[NSThread currentThread]);
        sleep(3);   
    }];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil];
        NSLog(@"  - %@",[NSThread currentThread]);
        });
}
 인쇄 결과:
2017-06-13 18:21:38.367  [29365:3382047]   - {number = 1, name = main}
2017-06-13 18:21:41.368  [29365:3382100]   - {number = 3, name = (null)}
  결론:
NSOperationQueue를 사용하면 알림을 받는 라인과 보내는 라인이 다르고 알림을 받는 라인이 주 라인에 있으면 UI를 새로 고칠 수 있다.둘.Xcode에서 unrecognized selector 오류가 보고된 경우
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    WWPerson *person = [[WWPerson alloc] init];
    [person test];
}
 person에 test 이 메시지를 보낼 때 runtime 라이브러리는 대상의 isa 지침에 따라 대상이 실제 속하는 클래스를 찾은 다음에 이 클래스의 방법 목록과 부류의 방법 목록에서 해당하는 방법을 찾아 실행한다. 맨 윗부분의 부류에서 상응하는 방법을 찾지 못하면 프로그램이 실행될 때 unrecognized selector sent to의 오류를 보고하고 붕괴된다. 그러나 그 전에objc가 실행될 때 프로그램 충돌을 피할 수 있는 세 번의 기회를 제공합니다.+resolveInstanceMethod: 또는 +resolveClassMethod:를 사용하면 프로그램이 붕괴되지 않도록 함수를 제공할 수 있습니다. 여기에 함수를 추가하면 시스템은 메시지 발송 과정을 다시 시작하고 그렇지 않으면 다음 메시지로 이동합니다.+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == NSSelectorFromString(@"test")) {
        /**
          class:  
          SEL:  
          IMP:   =>   =>   =>  
          type:  :void v ,id @ ,SEL : 
         */
        class_addMethod(self, sel, (IMP)test, "v@:@");
        return YES;
    }else {
        return [super resolveClassMethod:sel];
    }
}
void test(id self, SEL _cmd, NSNumber *meter) {
    NSLog(@"  - WWPerson");
}
2. Fast forwarding 만약에 목표 대상이
-forwardingTargetForSelector: 방법을 실현했다면runtime는 이 방법을 사용해서 우리에게 이 메시지를 다른 대상에게 전달할 기회를 주었다. 이 방법의 반환 값nil과 self만 아니면 전체 메시지의 발송 과정이 다시 시작될 것이다. 이때 발송 대상은 우리가 되돌아오는 이 대상이 되고 그렇지 않으면 다음 단계로 넘어갈 것이다.- (id)forwardingTargetForSelector:(SEL)aSelector {
    WWTarget *target = [[WWTarget alloc] init];
    if ([target respondsToSelector:aSelector]) {
        return target; //  WWTarget test 
    }else {
        return [super forwardingTargetForSelector: aSelector];
    }
}
3. Normal Fowarding은 상기 두 가지 방법이 모두 실현되지 않으면 세 번째 단계로 넘어간다. 이것은runtime가 우리에게 붕괴를 피할 수 있는 마지막 기회이다. 우선 함수의 매개 변수와 되돌아오는 값 유형을 얻고
-methodSignatureForSelector: 되돌아오는 값이면runtimenil이라는 메시지를 보내고 프로그램이 붕괴된다.함수 서명을 되돌려주면runtime는 NSInvocation 대상을 만들고 -doesNotRecognizeSelector: 메시지를 대상 대상에게 보냅니다.- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"v@:"];
    return signature;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    SEL selector = [anInvocation selector];// anInvocation selector/target/ 
    WWTarget *target = [[WWTarget alloc] init];
    if ([target respondsToSelector:selector]) {
        [anInvocation invokeWithTarget:target];
    }    
}
위의 세 단계가 모두 이루어지지 않으면 호출
-forwardInvocation:되어 프로그램이 붕괴됩니다.셋.깊이 복사와 얕은 복사
딥 카피: 컨텐트 카피, 복사된 객체는 이전 객체와 주소가 다릅니다.얕은 복사: 바늘 복사, 복사된 대상은 이전 대상의 주소와 같다.간단한 예제를 직접 사용하는 것이 좋습니다.
1. 가변 객체에 대한 작업
-doesNotRecognizeSelector:- (void)viewDidLoad {
    [super viewDidLoad];
    NSMutableString *mStr = [NSMutableString stringWithString:@"mStr"];
    NSString *copyStr = [mStr copy];
    [mStr appendString:@"123"];
    // mStr:0x60800007f440 - copyStr:0xa0000007274536d4
    NSLog(@"mStr:%p - copyStr:%p",mStr, copyStr);
}
  :1.    copy  ( )
      2. copy  copyStr NSString , copyStr 
NSMutableString appendString 。
2. 가변 객체에 대한 작업
copy- (void)viewDidLoad {
    [super viewDidLoad];
    NSMutableString *mStr = [NSMutableString stringWithString:@"mStr"];
    NSMutableString *mutableCopyStr =  [mStr mutableCopy];
    // str:0x608000260140 - mutableCopyStr:0x608000260440
    NSLog(@"str:%p - mutableCopyStr:%p",mStr, mutableCopyStr); 
}
  :1.    mutableCopy  ( )
      2. mutableCopy  mutableCopyStr  NSMutableString  
3. 불변 대상에 대한
mutableCopy 조작- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *Str = [NSString stringWithFormat:@"Str"];
    NSString *copyStr = [Str copy];
    // str:0x10147e128 - copyStr:0x10147e128
    NSLog(@"str:%p - copyStr:%p",Str, copyStr);
}
 :    copy  ( )
4. 불변 객체 작업
copy- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *mStr = [NSString stringWithFormat:@"mStr"];
    NSMutableString *mutableCopyStr = [mStr mutableCopy];
   // str:0xa0000007274536d4 - mutableCopyStr:0x60800026a680
    NSLog(@"str:%p - mutableCopyStr:%p",mStr, mutableCopyStr);
}
  :1.    mutableCopy   ( )
      2. mStr mutableCopy mutableCopyStr NSMutableString 
상기 서술한 바와 같이
mutableCopy만   조작하면 지침 복사(얕은 복사), 나머지는 내용 복사(깊은 복사)넷.키보드를 조정할 때 키보드의 "줄 바꾸기" 를 "발송 / 완성" 으로 바꾸는 방법 등
copy 속성을 설정하면 됩니다.    UIReturnKeyDefault,
    UIReturnKeyGo,//  
    UIReturnKeyGoogle,// google
    UIReturnKeyJoin,//  
    UIReturnKeyNext,//  
    UIReturnKeyRoute,//  
    UIReturnKeySearch,//  
    UIReturnKeySend, //  
    UIReturnKeyYahoo,//  
    UIReturnKeyDone,//  
    UIReturnKeyEmergencyCall,//  
    UIReturnKeyContinue NS_ENUM_AVAILABLE_IOS(9_0),//  
오.viewDidLayoutSubviews 및 layoutSubviews 호출 순서
returnKeyType 앞에서 호출viewDidLayoutSubviews 앞에서 호출layoutSubviews 앞에서 호출2017-06-14 10:31:35.215 layoutSubviews [7357:98975] -[ViewController viewDidLoad]
2017-06-14 10:31:35.215 layoutSubviews [7357:98975] -[WWView initWithFrame:]
2017-06-14 10:31:35.220 layoutSubviews [7357:98975] -[ViewController viewWillLayoutSubviews]
2017-06-14 10:31:35.220 layoutSubviews [7357:98975] -[ViewController viewDidLayoutSubviews]
2017-06-14 10:31:35.220 layoutSubviews [7357:98975] -[WWView layoutSubviews]
2017-06-14 10:31:35.221 layoutSubviews [7357:98975] -[WWView drawRect:]
여섯.분류 동적에 속성을 추가하는 방법
#import "WWView+Tools.h"
#import 
static char strKey;
@implementation WWView (Tools)
- (void)setDynamicStr:(NSString *)dynamicStr {
    /**
     id object:  
     const void *key: key 
     id value: value
     objc_AssociationPolicy policy:     NONATOMIC
     */
    objc_setAssociatedObject(self, &strKey, dynamicStr, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)dynamicStr {
    return objc_getAssociatedObject(self, &strKey);
}
 일곱어떻게view를 그림을 만들어서 로컬에 저장합니까
앨범에 접근하는 것과 관련이 있기 때문에, 우선plist 파일에
layoutSubviews 프로그램을 추가하여 앨범에 접근할 수 있도록 합니다.- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // self.testView: view  
     UIGraphicsBeginImageContextWithOptions(self.testView.bounds.size, 0, [[UIScreen mainScreen] scale]);
        [self.testView.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        UIImageWriteToSavedPhotosAlbum(viewImage, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
    });
}
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (!error) {
        NSLog(@" ");
    }else {
        NSLog(@"  - %@",error);
    }
}
 여덟만약 서버가 우리에게 되돌아온 데이터가 탭을 포함하고 있다면, 우리는 어떻게 불러와야 합니까
// html_content: html 
1. UILabel 
NSMutableAttributedString *attributeStr = [[NSMutableAttributedString alloc] initWithData:[html_content dataUsingEncoding:NSUnicodeStringEncoding] options:@{                                                                                                                                                                                     NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType                                                                                                                                                                                     }documentAttributes:nil error:nil];
self.contentLabel.attributedText = attributeStr;
PS: , 
2. UIWebView 
 // 15, rgb(124,181,236), 15, , 
 NSString *html_content = @" html ";
 NSString *htmls = [NSString stringWithFormat:@" 
"
                           " 
"
                           " 
"
                           " 
"
                           ""
                           ""
                           "window.onload = function(){
"
                           "var $img = document.getElementsByTagName('img');
"
                           "for(var p in  $img){
"
                           " $img[p].style.width = '100%%';
"
                           "$img[p].style.height ='auto'
"
                           "}
"
                           "}"
                           " %@"
                           ""
                           "",@"rgb(124,181,236)", html_content];
 [self.contentWebView loadHTMLString:htmls baseURL:nil];
아홉앱스토어에 올리는 게 너무 느리면 어떻게 해결해
Xcode - Open Developer Tool - Application Loader로 해결
십.Application Loader 패키지를 사용하여 App Store에 커밋하면 오류가 발생할 수 있습니다.
The filename  .ipa in the package contains an invalid character(s). The valid characters are:A-Z
,a-z,0-9,dash,period,underscore,but the name cannot start with a dash,period,or underscore.
해결 방법:Archive 이후의 가방은 중국어 이름을 다시 시도할 수 없습니다. XXX.ipa는 영어 이름으로 바꾸면 돼.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.