달력

9

« 2019/9 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  •  
  •  
  •  
  •  
  •  

iOS의 버전이 올라갈때마다 이런 저런 문제들이 생기기 마련인데 이번 iOS8에서는 UIImagePickerController(이하 이미지 피커)에서 약간은 심각한(?) 문제가 발견이 되었다.. Xcode 6에서 컴파일을 하면 괜찮기는 하지만 덩치 큰 프로젝트에 Xcode 6를 쉽게 적용하기는 쉽지않고 크고 작은 이슈들이 많이 야기될 수 있기 때문에 이건 시간을 가지고 천천히 수정을 해야 할 문제기 때문에 당분간은, 특히 업데이트를 목전에 두고 있는 마플 같은 경우 이미지 피커 문제가 좀 크다.. 그렇다고 그냥 묻어둘 수도 없고..


우선 발생하는 문제를 보자면 크게 두가지이다..



하나는 위 화면처럼 이미지 피커가 모달로 뜰 때 배경이 투명하게 보이는 문제.. 모달 창이 다 뜨고 나면 그제서야 내용물이 표시된다..

뭐 이건 크리티컬한 문제는 아닌데.. 요 다음 문제는 크리티컬하다..




종종 이미지 피커 객체를 한번 만들고 다시 피커를 띄우게 되면 좀전에 만들었던 이미지 피커를 재사용하도록 코딩을 하곤 한다..

한번 객체를 만들었던걸 다시 사용하는게 속도면에서 약간 유리할 수도 있기 때문인데, 바로 이때 위 화면과 같은 맹한 상태가 되어버린다.. 화면에 아무것도 표시가 안되고 심지어는 네비바에 취소 버튼조차 표시가 안되어서 창을 닫을 수도 없는 사태가 벌어진다..

이걸 해결하기 위해서는 이미지 피커 객체를 재사용하지 말고 피커를 띄울 때 마다 새로 생성해서 띄우면 된다.. 물론 첫 화면처럼 배경이 뚫려 보이기는 하지만 일단 Xcode 5.x 버전에서는 이것 말고는 이미지를 선택할 때, UIImagePickerController가 아닌 그냥 하나 통으로 만들어서 쓰는 방법 요렇게 두가지밖에 없어 보인다..


https://github.com/donobono/DoImagePickerController

이참에 틀에 박힌 UIImagePickerController말고 요런 훌륭한 오픈소스를 사용해보는 것도 좋을 것 같다..


매번 iOS가 업그레이드될 때마다 조용히 넘어가는 경우가 없네..

애플아.. 잘좀 하자.. 응?


Posted by 도노보노
2014.08.18 22:22

NSSet과 NSArray의 비교.. 개발 관련 이야기2014.08.18 22:22

예전에 NSSet을 어디에 써야 할 것인가 하고 잠깐 고민을 했던 적이 있었드랬다..

멍2

NSSet을 가장 쉽게 볼 수 있는 곳은 touchBegan 등과 같은 터치 이벤트를 받을 때인데, 딱히 이때말고는 그닥 쓸 일도 없었고 오히려 왜 이걸 array로 안넘겨주고 굳이 set으로 넘겨주는 것일까 약간은 불만이었드랬다..


암턴.. 그랬었는데.. 오늘 회사에서 파이썬 기초 교육이 있길래 신청해서 듣다보니 파이썬에도 set이 있어서 그 얘기가 잠깐 스치고 지나갔다.. 그런데 그때 딱 꽂힌건 set안에 특정 개체가 있는지 한방에 체크할 수 있다는 것과 set안에 새로운 객체를 넣을 때, 기존 객체와 겹치지 않게 새로운 객체들만 들어갈 수 있다는 사실이었다.. 왜냐하면 지난주 수요일하고 목요일에 사용자가 입력한 태그 스트링의 히스토리를 관리하는 부분에서 array를 사용했고 그러다보니 array를 다 뒤져가며 중복 체크를 하고, 기존 히스토리에 새로 추가를 할 때도 역시 중복 체크를 해서 집어 넣어야하는 부분이 있었는데 이걸 set을 사용하면 간단하게 해결이 됐었겠구나 생각이 됐기 때문이다..

생각중


                    
- (instancetype)init;	/* designated initializer */
- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt;	/* designated initializer */

- (instancetype)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithSet:(NSSet *)set;
- (instancetype)initWithSet:(NSSet *)set copyItems:(BOOL)flag;
- (instancetype)initWithArray:(NSArray *)array;



NSSet의 헤더파일을 보면 NSSet을 초기화하는 메쏘드는 이정도다.. 가만히 보면 NSSet 객체를 만들기 위해서는 array가 꼭 필요한 형태다..

나는 태그 히스토리를 plist 파일로 저장을 했다가 태그를 입력하는 화면으로 진입을 하면 그 plist 파일을 읽어서 array에 넣고 새로 입력받은 태그 스트링을 히스토리 array에서 체크를 해보는 방법을 사용했는데 NSSet은 아쉽게도 plist 파일을 직접 읽어서 set을 구성하는 방법은 없고 일단 NSArray 객체를 만들고 그걸 사용해서 NSSet 객체를 만들어야 하는 구조였다..


그러면 이때 고민을 해봐야 하는게 그렇다면 NSArray를 사용해서 NSSet을 만들때 얼마나 로드가 걸리느냐하는 부분이다..

그래서 테스트를 해봤다..

고고


                    
	_aData = [[NSMutableArray alloc] initWithCapacity:DATA_COUNT];
	
	for (int i = 0; i < DATA_COUNT; i++)
		[_aData addObject:[NSString stringWithFormat:@"%ld", random() % 23810298]];



일단 테스트 데이터를 만들어본다.. DATA_COUNT는 100000을 줘봤다..


우선 NSSet을 사용하는 경우다.. NSSet은 _aData를 사용해서 NSSet 객체를 만들고 특정 문자열을 검색해서 결과를 얻어내는 과정까지를 넣었다..



                    
	NSSet *set = [[NSSet alloc] initWithArray:_aData];
	NSString *str = [NSString stringWithFormat:@"%ld", random() % 23810298];
	if ([set containsObject:str])
		NSLog(@"YES");
	else
		NSLog(@"NO");




다음은 NSArray를 사용하는 경우.. NSArray는 _aData가 이미 만들어져있기때문에 100000번 문자열 체크를 해서 결과를 얻어기까지의 시간을 측정했다..



                    
	NSString *str = [NSString stringWithFormat:@"%ld", random() % 23810298];

	BOOL bFind = NO;
	for (NSString *strData in _aData)
	{
		if ([strData isEqualToString:str])
			bFind = YES;
	}
	
	if (bFind)
		NSLog(@"YES");
	else
		NSLog(@"NO");



코드는 역시 NSSet을 사용하는 것이 훨씬 깔끔하다..

각 메쏘드를 수행하는데 소요된 시간은 NSSet을 사용했을 때가 0.012103초, NSArray는 0.005886초가 나왔다.. NSArray가 약 2배정도 빠른 결과를 보여줬다..


다시 NSSet을 사용했을 때를 두 구간으로 나눠봤다.. 하나는 첫줄 NSArray에서 NSSet객체를 만들때 걸리는 시간과 다른 하나는 나머지 부분.. 각각 소요된 시간은 0.011662초와 0.000187초.. 즉 NSSet 객체로 변환을 하는 과정이 대다수의 시간을 소요했고 일단 한번 만들어진 NSSet 객체에서 특정 객체를 검색하는건 겁나 빠르다..


오늘 실험 결과.. NSSet 객체를 한번 만들어 놓고 여러번 사용하게 된다면 NSSet를 사용하는 것이 효율적이다.. 하지만 나처럼 특정 화면에서 한두번 사용할거라면 NSArray도 충분히 빠르기 때문에 굳이 NSSet을 쓸필요가 없을 것 같다.. 

하지만 오늘 이렇게 테스트를 해본 것도 있고하니 지난주에 만들었던 화면은 NSSet으로 바꿔봐야겠다.. ㅋ


끝!!

슈퍼맨



PS : 그러고 보니 NSSet의 기능 중에 두 NSSet 객체간의 교집합, 차집합, 합집합 같은 결과를 빠르고 편하게 구할 수 있는 것이 있는데, 기능은 그럴싸해보이기는한데 현실에서 쓰게 되는 일을 아직 못봤네.. -_-;;

느낌표

Posted by 도노보노