달력

07

« 2017/07 »

  •  
  •  
  •  
  •  
  •  
  •  
  • 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
  • 31
  •  
  •  
  •  
  •  
  •  

지난 9월 9일에 업데이트 신청한 앱이 딴지 없이 18일인 오늘 9일만에 승인되었습니다.


이번 2.0 버젼에서 크게 달라지는 점은 앱을 통해 새소식, 새이슈를 접하기 쉽도록 앱을 기획하였습니다. 주요기능을 설명드리면,


  1. PUSH알림을 통해서 새소식 알림을 받을 수 있습니다. (new)
  2. 거의(?) 매일 업데이트 되는 뉴스/이슈/사람 정보를 확인할 수 있습니다. (new)
  3. 뉴스/이슈/사람에 대한 검색을 할 수 있습니다. (new)
  4. 이슈/사람에 대한 즐겨찾기를 할 수 있습니다. (new)
  5. 인물정보에서 국회의원에 대한 의정활동 정보를 "열려라 국회(참여연대 운영)"에서 검색할 수 있습니다. (new)
  6. 인물에 대한 관련 이슈를 볼 수 있습니다. (기존과 동일)


이번에 앱을 업데이트하면서 활용성이 떨어지는 몇몇 기능(보관함,정치인SNS 등) 들은 삭제하고 앱을 켜서 새로운 정보를 조회하는 기능 위주로 구성하여 활용성과 편의성을 높였습니다.


기존 1.x 기능과 많이 바뀌니 그 점 유의하시어 앱을 업데이트하시길 바랍니다.

감사합니다.


View in App Store 


P.S) 아이패드 버젼에서 즐겨찾기 항목을 빠르게 여러번 선택할 경우 비정상 종료되는데 조만간 패치버젼을 올리겠습니다.


[스크린샷 - 아이패드]



[스크린샷 - 아이폰]





저작자 표시 변경 금지
신고
2012.08.20 01:41

Strong, Weak, Assign 살펴보기 개발기술/iOS2012.08.20 01:41

ARC가 나오면서 새로운 Property로 strong, weak이 추가되었다. 알다시피 strong은 강한 참조, weak은 약한 참조라는 의미이다. iOS 4.x에서 썼던 retain, assign( unsafe_unretained)의 대체 개념이라고 알고 있는데 어떤 개념으로 쓰이는 것일까? 그리고 weak과 assign은 어떻게 다른 것일까? 이런 궁금증이 발동하여 테스트 코드를 작성해보았다. 아래 코드를 보자.


@interface SMViewController ()

@property (nonatomic, strong) NSObject *strongObj;
@property (nonatomic, weak) NSObject *weakObj;
@property (nonatomic, assign) NSObject *assignObj;

@end

@implementation SMViewController

- (void)printAddress {
    NSLog(@"strong addr : 0x%x", (unsigned int)self.strongObj);
    NSLog(@"weak addr   : 0x%x", (unsigned int)self.weakObj);
    NSLog(@"assign addr : 0x%x", (unsigned int)self.assignObj);
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"> init values");
    self.strongObj = [[NSObject alloc] init];
    self.weakObj = self.strongObj;
    self.assignObj = self.strongObj;
    [self printAddress];
    
    NSLog(@"> set strongObj to nil");
    self.strongObj = nil;
    [self printAddress];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"> move another stack");
    NSLog(@"> will die at assignObj");
    [self printAddress];
}


코드의 내용은 strong, weak, assign 값을 선언하고 strongObj에 Object을 할당한 다음 weakObj와 assignObj에 strongObj을 세팅하고 생명주기가 어떻게 되나 살펴보는 내용이다.


결과는 이러했다.


> init values
strong addr : 0x6a20320
weak addr   : 0x6a20320
assign addr : 0x6a20320
> set strongObj to nil
strong addr : 0x0
weak addr   : 0x6a20320
assign addr : 0x6a20320
> move another stack
> will die at assignObj
strong addr : 0x0
weak addr   : 0x0
== BAD ACCESS ==


처음 시작할 때는 strongObj의 강한 참조값이 살아 있어 weakObj, assignObj의 주소값이 모두 찍힌다. strongObj값을 날려버리고 난 후에는 strongObj의 주소는 0x0이 되고 다른 Obj들은 그대로이다. 


그런데 결과의 12라인을 보면 다른 스택으로 넘어가는 순간 weakObj의 주소값이 0x0으로 바뀐 걸 알수가 있다. 코드로 아무런 조치도 안 했는데 자동으로 값이 바뀐 것이다. weakObj의 약한 참조가 strongObj의 오브젝트가 메모리에서 사라지면서 풀려버린 것이다!! (ARC를 쓰면 오브젝트에 대한 BAD ACCESS의 위험이 대폭 줄어들 것이라는 예상을 할 수가 있다.)


그리고 그 다음 라인에서 assignObj의 주소값을 찍으려는 순간 앱은 BAD ACCESS 내뱉고 죽어버린다. assignObj가 가지고 있는 address의 오브젝트에 대한 잘못된 접근을 했다는 말인데 메모리에서 오브젝트가 사라지더라도 값은 그대로 남아있어 문제를 일으켰다는 것을 알 수 있다.


이 간단한 테스트로 weak과 assign의 차이를 알 수 있고, strong, weak의 쓰임, assign의 쓰임에 대해서도 얼핏 짐작할 수가 있다.


정리하면, strong, weak은 오브젝트을 참조할 때 쓰고, assign은 int, float, double 등과 같은 primitive type에 대해값을 할당할 때 쓰면 되겠다.


TestWeakAssign.zip


저작자 표시 변경 금지
신고

ARC, non-ARC 소스가 같이 있는 프로젝트에서 메모리 해제가 잘 될까?


궁금해서 데이터 오브젝트를 하나 만들어 해제하는 간단한 테스트 프로젝트를 만들어 보았다.



TestARC.zip



프로젝트에 대해서 대충 설명하면, ARC을 사용하는 프로젝트를 만들고 ARC, non-ARC 소스 두개를 만든다.


@interface SMData : NSObject

@property (nonatomic, strong) NSData *data;

@end


@implementation SMData

- (id)init {
    self = [super init];
    if (self) {
        self.data = [NSMutableData dataWithCapacity:1024*1024];
    }
    return self;
}

@end

<ARC소스는 strong을 써서 1메가를 할당하는 오브젝트>


@interface SMData_noARC : NSObject

@property (nonatomic, retain) NSData *data;

@end

@implementation SMData_noARC

@synthesize data = _data;

- (id)init {
    self = [super init];
    if (self) {
        self.data = [NSMutableData dataWithCapacity:2*1024*1024];
    }
    return self;
}

- (void)dealloc {
  [_data release];
  [super dealloc];
}

@end

<non-ARC소스는 기존 방식대로 retain을 쓰고 2메가를 할당하는 오브젝트>



그리고 컴파일 에러가 나지 않게 non-ARC소스에는 -fno-objc-arc 플래그를 지정한다.



이제 Alloc, Release 하는 버튼을 만들어 데이터 오브젝트를 생성하고 해제할 수 있도록 만든다.


- (IBAction)onAlloc:(id)sender {
    self.data = [[SMData alloc] init];
}

- (IBAction)onRelease:(id)sender {
    self.data = nil;
}

- (IBAction)onAllocNoARC:(id)sender {
    self.data_noARC = [[SMData_noARC alloc] init];
}

- (IBAction)onReleaseNoARC:(id)sender {
    self.data_noARC = nil;
}


<실행화면>



이제 메모리를 생성하고 해제하는 동작이 잘 되는지 Instrument 을 통해서 확인한다.


Xcode 메뉴의 Open Developer Tool에서 Instrument을 실행한다.




Allocations을 선택한다.



Choose Target > Attach to Process 에서 TestARC을 선택한후 Record을 누르면 Allocations 모니터링을 할 수가 있다.




버튼을 누를때마다 그래프가 오르락 내리락 하는 걸 통해 정상적으로 메모리가 할당되고 삭제되는걸 확인할 수가 있고, 통계 수치를 통해서도 알 수가 있다. (Malloc 1.25MB는 ARC로 만든 데이터, Malloc 2.50MB는 non-ARC로 만든 데이터)





이로써 ARC, non-ARC 둘다 섞인 소스도 메모리 관리가 정상적으로 된다는 것을 알게 되었네요...

의심이 많다보니 오늘은 뻘짓을 좀 해봤습니다. ㅋㅋ



TestARC.zip



저작자 표시 변경 금지
신고


티스토리 툴바