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에 따라 라이센스가 부여됩니다.