1. var let으로 바꾸지 말자. 처음부터 let으로 하려고 노력하고 안되면 var는 var 그대로...


Cannot pass immutable value as inout argument: 'ret' is a 'let' constant


var가 리팩토링 중 immutable 해져서 let으로 바꾸었는데 &로 주소 넘기기는 안되나 보다. 굳이 바꾸지 않더라도 copy로 넘기고 싶진 않은데, 따져보면 상수로 저장된게 카피 될리가 없지.


Use of extraneous '&'


같은 류. 구조를 수정해서 var를 let으로 바꾸었다고 좋아했는데... 걍 바꾸지 말자.


2. void pointer는 언제나 만능이었다. JAVA 에서는 Object와 interface,  swift에서는 protocol 뿐. 상위 객체 포인터 믿지마. 안돼.


Cannot convert value of type 'jhSceneTimeLine' to expected argument type 'inout jhScene'


jhSceneTimeLine 이 jhSscene를 상속받았는데도 불구하고 상위 포인터로 하위 object를 받을 수 없었다.


자바에서는 다형성이 잘 지켜져 때문에 뭣하면 최상위 Object로 넘기고(void 포인터) 캐스팅해서 쓰면 되었는데...


swift에서 그 정도의 파격은 허용되지 않았다.  그래서 상위 protocol을 선언하고 모두 상속받게 하여 상위


포인터(인스턴스 변수)를 프로토콜로 하면 모두 통용된다.


SWIFT 나름의 개념이 있지만 포인터로 이해하면 리팩토링시 이해 안되는 부분은 없다.


3. 너무 복잡한 일반화는 독... 걍 클래스 다이어그램을 처음부터 잘 그려야 함.


Cannot assign value of type 'T' to type 'T'


일반화 하면서 만나는 에러, <T>를 상속받는 녀석은 꼭 <T>를 명시하고 builder pattern 적용할 때도 명시해야 한다. 에러라도 나오면 다행인데 builder pattern에 적용했을 때 <T>를 안 적어주고 생성했는데 잘 되더라. 결국 논리 오류로 나오고 찾기 빡쌨음 ㅠ. 4.2 버전인데 5가면 요런 에러 필터링 기능이 더 좋아지겠지.


4. 프로퍼티는 처음부터 누가 가질지 잘 설계하자. protected 없다. 빈자리 크다.


Cannot override with a stored property 'mPanels


새로운 구현인데 원래 구현이 아까워 제네릭화 하다가 프로퍼티 오버라이딩 중 생긴 오류.


같은 이름을 쓰려면 접근 제한자(privagte)을 통하는 방법외엔 없다.


Method does not override any method from its superclass


Value of type 'jhType1graphLayer' has no member 'superScene'

Use of unresolved identifier 'panelID'


접근 제한자 때문에 여러 상황이 생긴다.


protected가 없으니 JAVA처럼 생각해서 설계하거나, 리팩토링 하는 것은 그만둬야 겠다.


객체지향이 들어갔으니 객체 단위로 생각해야 하는데, 모듈 단위는 사실상 폴더 단위라... ㅡㅡ;


하긴 fileprivate은 또 파일 단위인데 프로그래밍 하다보면 한 파일에 하나의 class를 넣는게 맞다는


생각이 참 많이 든다. 이런게 잘 안되니 extension 남발하게 된다. extension이나 데코레이션 패턴은


사실상 작은 단위의 설계가 되지 않는다. 작은 프로젝트는 코딩하면서 설계도 자동으로 되는데 말이다.


5. 제네릭 리팩토링이 자바에 비해 너무 힘들었다. 배 GoF다.


Cannot specialize non-generic type 'jhBarGraph'

프로퍼티나 function이 비슷한 모양(접근 제한자, 인자, 인자에 들어가는 데이터 타입 등등)

이면 편한데 아닌 경우 빡쌨다.


건네 줄 옵션이 많은 애들은 일반화 하면서 


타입 뿐 아니라 파라미터까지 달라져야 한다면 빌더 패턴이 답이다.


func build() -> jhPanel<T> {


switch mGtype {


case .LINE:


return jhLineGraph<jhScene>(frame: CGRect(x: x, y: y, width: width, height: height))


case .BAR:


return jhBarGraph<jhScene>(frame: CGRect(x: x, y: y, width: width, height: height))


case .TYPE1:


return jhType1graphPanel<jhSceneTimeLine>(frame: CGRect(x: x, y: y, width: width, height: height), scene: superScene)


case .TYPE4:


return jhType4graph<jhSceneTimeLine>(frame: CGRect(x: x, y: y, width: width, height: height))


}


안드로이드 스튜디오도 참 많이 좋아졌지만, 이클립스에 있던 리팩토링 기능만 해도 지금의  swift보다는 더 강력했다. 제네릭으로 어느 정도 꼬이니 이제 cmd+shift+O 도 찾고자 하는 클래스를 잘 못 찾고 헤매는 경우가 많더라.



스위프트 4.0 -> 4.2 짜증

'NSAttributedStringKey' has been renamed to 'NSAttributedString.Key'


6. lvalue 옵셔널 모든 에러 안 잡더라 대입 잘된다. 조심하자.


 옵셔널은 사실상 null check 에 편한 문법과 설계상 고려하라고 만든 문법이다. 그러나 특정 상황에서는 무조건 null이 안되는 경우가 있기 때문에 옵셔널을 전달받은 어떤 객체가 꼭 옵셔널일 필요는 없다. 그래서 !가 있는데 !는 사실 안쓰는게 맞거든... ! 쓸바엔 Assert가 맞지.



이렇게 예민한 이유는 컴파일/런타임 에러 없는 논리 오류 하나 찾기가 참 어려웠는데, ...


답은 Optional? 에 대입해서였다. 옵셔널이 윗단에서 주구창장 내려온 경우 대입할 때 ?를 붙여서


대입해 버렸는데, 참... 대입 잘되더라.


이런 오류 날 것 같지?


Initializer for conditional binding must have Optional type, not '[CGFloat]'


안나는 경우도 있었다. 정리하면서 했던게 아니고 논리 오류 찾는데 힘들었기에 원칙으로 남겨둔다. 엘벨류 조심하자.


아니면, 한번 옵셔널은 계속해서 옵셔널로 하는게 좋겠다. 상위단에서 있을 수도 없을 수도 있는게 하위단으로 내려간다면 하위단에는 무조건 있는 것으로 바꿔야 하는 경우가 있었다. 널체크 하고 넘기는데 사실, 그게 그 객체를 구성하는 프로퍼티중에 핵심적인 것은 아니어서 있으나 마나한... 


반대의 경우도 있었다. 옵셔널이 아니었는데 상속 구조상 어느 객체에는 있고 어느 객체에는 없는

프로러티가 되어 버린 경우, 두 가지 클래스에 먹히는 제네릭 클레스를 만든 경우... 해당 프로퍼티는

옵셔널이 되어야만 했다.


최대한 이런 경우를 없애야 하는데 개념상 그렇게 구현을 해야 하고...


그렇게 꼬이다 보면 결국 디자인 패턴을 쓰게 된다. 오늘 파일을 나눈 방식을 정리하면,


Separation

- flag

    - flag + if, switch 원초적이나 시온이다.

    - C에서는 #define 이 짱이지. #ifdef, #ifndef

- file

    - separated file + call(자바 때부터 뭐... startActivity using intent, function call, pushViewController...) 콜만 잘되서 연결되면 오케이 였다. 리눅스에서도 그랬잖아. 시스템 콜 잘 부르면 되고... 커널 API만 잘 쓰면 되고.

    - separated file + builder pattern - passing self again and again(늘 고맙지)

    - separated file + proxy pattern(related with memory managements) - can't using directly 객체 단위 캡슐화닷!

    - separated file + adapter pattern - overriding, generic, converting ... whatever use current class or method 고치기 힘들어서 걍 중간 다리 만들었다.

    - separated file + decorator pattern - also passing object via parameter(서브 클래싱 대신 기능 확장용... 익스텐션이 낫다.)

    - separated file + bridge pattern - also passing object via parameter(구현부에서 추상층을 분리 ㅡㅡ; 제네릭화 ... 개고생 어댑터가 낫다.)


이정도 인데 사실 structural 패턴을 쓰다보면 파라미터에 함수 포인터를 넣어서 자기 객체를 계속해서 넘겨 주느냐 안 넘겨 주느냐가 핵심이다. 안 넘겨 주면 중간에 다리 역할을 할 친구를 찾는거고.


결국 소스를 가장 적게 수정하는 것은 싱글톤을 넣는게 최고.


객체 단위니 싱글톤이고 그 개념은 결국 플래그고... 플래그는 결국 세마포어고...


믓튼 


풀 때는 guard로만 풀자고 다짐해 본다.


몇몇 메모리 오류가 났는데,


Kernel Alloc Once 8K 2


MALLOC 293.3M 126


MALLOC guard page 176K 39


MALLOC_LARGE (reserved) 516K 2 reserved VM address space (unallocated)


swift 역시 메모리 관리 한다고 욕본다.


추상화 개념은 추상화 그대로 이해하고 싶은데, ... 결국 메모리 중심으로 생각하는게 정답이라는 생각.


var
 str = "A String"

withUnsafePointer(to: &str) {

    print(" str value \(str) has address: \($0)")

}



메모리 안에서 우린 평안할 지어다.


쓰다보니 뇌 컨디션이 좀 돌아온다.




+ Recent posts