BLOG main image
분류 전체보기 (92)
Cocoa Touch (11)
Cocoa (10)
Objective-C (13)
Swift (6)
Development (11)
Tools (11)
Books (7)
etc (21)
Application release (1)
Document Project (1)
105,797 Visitors up to today!
Today 0 hit, Yesterday 2 hit
daisy rss
tistory 티스토리 가입하기!
'Swift'에 해당되는 글 6건
2015. 7. 1. 13:57

평소에 ARC를 별로 쓰지 않다가 샘플 프로젝트를 ARC로 하고 있는데 재미있는 내용이 보입니다.

performSelector: 메소드에 관한 것인데, MRR의 경우 performSelector의 사용에 있어서 아무런 문제가 없습니다.

하지만 ARC의 경우 warning을 내는 경우가 발생하네요. 아래와 같이 static한 selector를 사용하는 경우는 문제가 되지 않습니다.


[object performSelector:@selector(myMessage)];


하지만 이렇게 사용해서는 selector를 제대로 쓰는 거라 보기는 좀...

만일 SEL에 담긴 임의의 selector를 사용하게되면 “PerformSelector may cause a leak because its selector is unknown”이라고 메시지가 뜹니다.

아래와 같이 코딩을 하면 그런 문제가 생기지요.


[object performSelector:mySelector];


이유는 return type 때문입니다. return type이 객체인지, primitive type인지 autorelease를 해줘야 하는지 retain된 상태인지 컴파일러가 나는 모르겠다는거군요.

뭐 MRR의 경우 컴파일러가 몰라도 개발자가 알아서 할것이기 때문에 굳이 이런 warning을 낼 필요가 없었던 것이지요.


하지만 급기야 swift에 가서는 performSelector 자체를 없애버렸습니다(이전 글에서 썼듯이)!!


여기서 조금 중요한 개념적인 문제를 한번 짚고 넘어가 보죠.

OOP란게 뭔가 잔득 복잡한 이야기 같지만, OOP에서 가장 중요한 키워드만 뽑아보라면 저는 단연코 “객체”, “관계”, “메시지”라고 이야기 하고 싶습니다. “클래스”, “맴버 함수”, “상속” 따위가 아니라는 말이지요.


Objective-C의 performSelector는 다른 언어와 Objective-C가 구별되는 가장 중요한 차이 중 하나인 “메시지”를 대표하는 기능입니다.

Objective-C의 경우 객체만 추상화 되는 것이 아니라 메시지도 추상화 되기 때문에 이 기능을 잘 이용하면 매우 간결하고 아름다운 코드를 만들어 낼 수 있습니다. 그런데 애플은 결국 서서히 메시지의 추상화를 제거해버리는 쪽으로 방향을 잡았군요.

아주 로레벨인 메모리 관리를 하는 방법을 컴파일러가 알아내기 힘들다는 이유로 하이레벨의 중요한 개념 하나를 날려버렸군요. 쩝...


결국 Swift의 경우 메시지 전달은 매우 명시적고 해당 클래스에 강하게 묶여있습니다. 우리는 이것을 맴버 함수 호출이라고하지요.

반면 Objective-C의 경우 메시지 전달과 메소드 호출은  완전 다른 이야기입니다. 어떤 객체에든 메시지를 보내는 것이 자유이고 메시지를 받은 객체는 그 메시지에 대해 어떤 메소드를 이용해서 반응할지 동적으로 결정할 수 있습니다.


여러분은 어느 쪽에 손을 들어주실 것인가요?



Name
Password
Homepage
Secret
2015. 6. 23. 00:40

Swift에서 사라진 performSelector를 대신해서 구현하는 많은 방법들, 예를 들면 GCD, 클로져, 타이머, 심지어 NSThread를 동원하는 방법들이 거론되고 있지만 진정한 핵심을 놓치고 있는것 같다.
대체 가능한 수단이 존재하는 것은 사실이다. (물론 훨씬 지저분한 방법으로...) 하지만 가장 중요한 것은 객체와 메시지로 설명되는 객체지향의 가장 기본적인 내용 및 그것을 가장 우아하게 구현한 ObjC의 기능을 Swift에는 넣지 않았다는 것이다.
객체지향의 관점에서 Swift는 ObjC보다 한참 못한 언어인것 같다.

Name
Password
Homepage
Secret
2015. 6. 20. 00:55

종암님이 예전이 쓰셨던 글을 봤네요.

 

https://jongampark.wordpress.com/2014/10/16/swift-f-script/

 

오랫동안 잊고 있었던 수많은 삽질들의 기록을 어찌 이렇게 잘 해두셨는지.. :)

Swift가 이전 삽질과는 다른 것이 분명해 보이네요. 앞으로 어떻게 될지 궁금하기도 합니다.

결국 Cocoa Framework의 새 주인은 수많은 삽질끝에 Swift로 정리될 것인지...

Name
Password
Homepage
Secret
2015. 6. 19. 17:53


어떤 함수 안에서 특정 변수의 조건이 만족될 때 실행되어야 하는 코드가 있다고 하자

if-let문을 사용하게 되면 아래와 같이 if-let 피라미드를 쌓아 올리게 된다.


        if let id = info[“id"] as? NSNumber {

            if let userId = info[“userId"] as? NSNumber {

//  구현

            }

        }

        return



이렇게 피라미드가 쌓이는 꼴을 못보겠다면 다음과 같은 방법도 있다.


        if let id = info[“id"] as? NSNumber,

           let userId = info[“userId"] as? NSNumber {

// 구현

}

return


하지만 이 역시 별로 예뻐보이지는 않는다. 그래서 early exit를 하는 코드를 작성하기로 한다.


        let id = info[“id"] as? NSNumber

        if id == nil {

            return

        }

        let userId = info[“userId"] as? NSNumber

        if userId == nil {

            return

        }


뭔가 주절 주절 널어지는 느낌을 지울 수 없다.

그래 guard를 한번 써보자.


        guard let id = info[“id"] as? NSNumber,

              let userId = info[“userId"] as? NSNumber else {

                return

        }


이거나 if-let,let else 나... 아래를 보자. 어차피 else가 들어가긴 마찬가지 아닌가?


        if let id = info[“id"] as? NSNumber,

           let userId = info[“userId"] as? NSNumber { } else {

                return

        }


 게다가 나는 id나 userId같은 변수는 필요없다. 안쓰니까 친절하게 워닝까지 내어준다. let을 제거하기로 마음을 먹는다.


        guard info["id"] as? NSNumber != nil && info["userId"] as? NSNumber != nil else {

            return

        }


그렇게 하니 이번에는 조건이 뒤집어진다. 그러니까 “id도 있고 userId도 있으면”이 아니면 return인게다. 이건 말을 마구 꼬으는 느낌이다.

이걸 그냥 if문을 사용하면 아래와 같아진다.


        if info["id"] as? NSNumber == nil || info["userId"] as? NSNumber == nil {

            return

        }


id가 없거나 userId가 없으면 return이다. 훨씬 간결하네.

그럼 우리는 이것을 ObjC에서는 어떻게 표현했는지 보자.


        if (![info objectForKey:@"id"] || ![info objectForKey:@"userId"]) {

            return

        }

        

으응???


그래서 그나마 가장 합리적인 선택... 아래와 같은 방법을 쓰기로 했다.


        guard let _ = scheduleInfo["id"] as? NSNumber, let _ = scheduleInfo["userId"] as? NSNumber else {

            return

        }

Name
Password
Homepage
Secret
2015. 6. 18. 18:09

Objective-C를 처음 접했을 때 가장 마음에 드는 것 중 하나가 collection에 저장될 수 있는 객체의 타입이 달라도 된다는 것이었다. 하나의 array안에 NSString과 NSNumber를 같이 넣는 다는 것은 C++을 주로 사용하던 나에게는 정말 충격적인 일이었다.


세월이 흘러 어느덧 Swift라는 새로운 언어에 익숙해져야 하는 순간이 왔다. 첫 인상부터 별로였던지라 (genertic이 첫 인상을 나쁘게 하는데 일조했다.) 마지못해서 슬슬 보고는 있는데... 역시 오늘 완전 사람 속을 뒤집어 놓는 케이스를 만났다.


JSON 데이터를 파싱하는 NSJSONSerialization 클래스를 한번 보자.


+ (id nullable)JSONObjectWithData:(NSData * nonnull)data
                          options:(NSJSONReadingOptions)opt
                            error:(NSError * nullable * nullable)error // nullable은 도대체 또 뭐냐


위는 Objective-C의 경우이다. 리턴 타입이 id라고 되어있지만 우리는 경험상 이것이 NSArray거나 NSDictionary임을 알고 있다.

그냥 안에든 객체를 id로 다루면 아무 문제없이 깔끔하게 원하는 작업을 수행할 수 있다.


하지만...


다음은 Swift이다 . Objective-C에서 id는 즉 Swift에서 AnyObject. 뭐 이 정도는 봐줄만 하다.


class func JSONObjectWithData(_ data: NSData,
                      options opt: NSJSONReadingOptions) throws -> AnyObject


가지고 있는 JSON이 Dictionary라는 사실은 알고 있다. 그래서 다음과 같은 방법으로 casting을 시도했다.


let dict = jsonObject as? [AnyObject: AnyObject]

let dict = jsonObject as? [AnyObject: Any]


Objective-C에서는 key는 NSCopying만 지원하면 된다고 규정하고 있고 value는 id이면 뭐든 가능하다.

첫 시도는 가당찮게 에러를 보는 것으로 끝났다. 그럼 어떻게 하면 되지?


let dict = jsonObject as? [NSCopying: AnyObject]


위는 어처구니 없는 다음 시도였으나 될리가 없다. 안될 것이라고 생각하고 쓴 멍청한 코드다.

잠시 머리를 돌려본다. Dictionary의 key 조건은 hashable이다. 이렇게 해본다.


let dict = jsonObject as? [HashableAnyObject]


역시 에러다. 이쯤되면 조금 짜증이 나기 시작한다. 다시 다음과 같은 방법들도 써본다


let dict = jsonObject as? Dictionary<AnyObject, AnyObject>

let dict = jsonObject asDictionary<HashableAnyObject>

let dict = jsonObject asDictionary<AnyObjectAnyObject?>


역시 안된다. 이쯤되면 완전 짜증이 머리 끝까지 솟구친다.

키를 string으로 제한시켜본다.


let dict = jsonObject as? Dictionary<String, AnyObject>

let dict = jsonObject as? [StringAnyObject]


아... 이제 된다. 키가 String이 아닌 dictionary나 가변적인 경우는 어떡하지? 하지만 이런 고민은 잠시 접어두자. 된것만 해도 어디냐며...

여기에 키의 타입을 바꾸거나 value의 타입을 바꾸면 또 안된다. 아, value를 AnyObject?로 해도 안됨을 주의!


이 사단은 별로 유용하지도 않은 generic이라는 이상한걸 들고와서 벌어진 일이다.

Objective-C를 사용하던 사람입장에서는 Swift의 casting과 generic이 얼마나 사람을 열받게  만드는지 한번 느껴보시기 바란다.

yagom | 2015.06.19 01:53 신고 | PERMALINK | EDIT/DEL | REPLY
저는 그래서 JSON 파싱은 Objective-C로 해요...^^; 마음속에서 솟구쳐 오르는 저 무언가를 참기는 힘들 것 같아요...ㅎㅎ
maccrazy | 2015.06.19 09:40 신고 | PERMALINK | EDIT/DEL
:) 그런 방법을 쓰시는군요.
저는 한 프로젝트에 여러 언어를 섞어쓰는 것을 좀 싫어해서 swift로 하면 최대한 swift로 하고 있는데 계속 마음속에서 뭔가가 솟구치는군요. ㅋㅋ
하지만 뭐 어쩌겠습니다. 돌이키기엔... 애플이 그리로 가겠다는데 방법이 없네요.
Name
Password
Homepage
Secret
2014. 6. 10. 13:53

WWDC 2014에서 애플은 Swift라는 새로운 언어를 발표했습니다.

많은 개발자가 놀라워했고 당황스러움과 함께 우려 반 반가움 반 뭐 그런 분위기였던 것 같습니다.


Swift에 대한 첫인상을 대충 이야기 하자면,

“스크립트 언어스러움을 표방하며 최신 언어 트랜드를 적절히 잘 합쳐서 재미있게 코딩을 할 수 있는 별 특색 없는 언어”라고 표현하고 싶습니다.

재미있는 현상은 주변 개발자들에게 Swift의 첫인상을 물어보면 하나같이 자신이 알고 있던 언어와 닮았다고 합니다. :)

스칼라, 자바스크립트, 액션스크립트, 파이썬… 뭐 그만큼 다른 언어에서 빌려 온 부분이 많다는 것이겠지요.


전반적으로는 긍정적인 분위기인듯 합다.

제 개인적인 견해는 앞서 말씀드린 첫인상 한 줄 표현과 함께 “굳이 왜 새 언어를 만들었을까?”로 요약될 것 같습니다.

기존의 괜찮은 언어들이 꽤 많은데 별로 새로울 것도 없는 언어를 새로 만들 필요까지 있었을까 하는 것이지요.

그러다보니 차라리 루비같은 언어를 사용하는 것이 더 좋지 않았을까 싶기도 합니다. 기존 루비 개발자들까지 끌어들일 수 있을테니까요.


그러지 못한 이유가 살짝 보이기도 합니다.

문제는 ARC입니다. 최신 언어들은 기본적으로 GC를 가지고 있는데 Swift는 GC가 없고 ARC 기반으로 동작합니다.

즉, GC를 기반으로 동작하는 언어를 그대로 가져오기에는 많은 어려움이 있었을 것이라는 생각도 듭니다.

애플이 LLVM-ARC를 계속해서 밀고 있는 상태에서 GC를 쓰기도 조금 어색한 구석이 있는 것은 사실입니다.

하지만, ARC를 사용하게 되면서 언어를 구성하는데 필수적이지 않은 지시어들과 룰이 많이 포함되었습니다.

앞서 여러 포스트에서 제 개인적으로 ARC에 대한 부정적인 견해를 많이 피력했었는데요, 지금도 마찬가지입니다.

ARC는 얼핏 봤을 때 매우 단순한 것 처럼 보이지만 실상은 꽤 복잡한 룰을 가지고 있습니다.

결국 retain-release 구조를 뒤로 숨기기 때문에 어쩔 수 없이 발생하는 문제인데요, 결국 이런 부분들이 언어를 불필요하게 복잡하게 만드는 경향이 있습니다.


그렇다면 Swift는 OOP 언어인가요?

글쎄요. 모양 자체는 OOP언어의 기본 형태를 따르고 있지만 access modifier가 없습니다.

해당 이슈에 대해서 Apple discussion forum에서 논의가 있었는데요, 결국 애플 개발자가 access modifier를 추가해주겠다는 것으로 결론이 났습니다.

제 생각이 틀렸는지 모르겠지만 OOP언어에서 access modifier가 없다는 것은 상상도 할 수 없었거든요.


그렇다면 Swift는 함수형 언어인가요?

글쎄요. 가이드를 대충 보기는 했지만 그 어디에서도 함수형 언어라는 인상을 받을 수는 없었습니다. 굳이 따지자면 OOP언어 + 함수형 언어 컨셉인 스칼라와 좀 닮긴 했지만 문법이 닮았다고 같은 부류의 언어로 구분하기는 어려울듯 합니다.


Swift Programming Guide 그 어디를 봐도 이 언어에 대한 명확한 정의는 없습니다. 아, 그냥 “재미있고 빠르게” 만들 수 있다는 정의가 있기는 하군요.

결국 Swift의 기본 컨셉은 “재미있고 빠르게”인듯 합니다.


그렇다면 Swift는 “재미있고 빠르게”의 컨셉에 맞을까요?

뭐 비교적 맞다고 생각은 듭니다. 저도 가이드 문서를 보면서 꽤 재미있는 언어라고 생각하기는 했습니다.


그렇다고 해서 정말 프로젝트를 “재미있고 빠르게” 수행 할 수 있을까요?

불행히도 아직까지 제 인상에는 “글쎄요”입니다.

모르긴 몰라도 현재 작성된 iOS, Mac OS 코드를 Swift로 바꾸는 작업, 또는 재작성 하는 작업은 매우 힘들고 피곤한 일이 될 것이기 때문입니다.

물론 매우 간단한 구조에 Swift에서 제공하는 기능만 쓴다면 “재미있고 빠른” 작업이 가능할지 모르겠습니다만, 세상일이 어디 그런가요?

기존에 있던 C API들(쿼츠, 퀵타임 등등)의 사용이 매우 번거로워질 것이 눈에 보이고요,

기존에 있던 수많은 오픈소스 C/C++/ObjC 코드들을 사용하는 것 역시 매우 번거로운 작업이 될 것이 뻔하기 때문입니다.


물론 저 역시 Swift를 계속 들여다 보며 공부할 예정이지만 이것으로 본격적으로 프로젝트를 수행할 날이 언제 오게 될지는 조금 더 지켜봐야 할듯 합니다.



Name
Password
Homepage
Secret
prev"" #1 next