2015年10月2日 星期五

Objective-C 基本觀念複習

雖然現在Swift已經出到2.0了,但是大多數公司還是使用Objective-C為主力語言。因此,適時複習一下觀念還是很有必要的。網路上有一些不錯的題目,例如 招聘一个靠谱的 iOS、面試 iOS 工程師的一些題目、如何面试 iOS 工程师?、上级向的十个iOS面试问题。也有一些網友給出了自己的解答,例如:https://github.com/ChenYilong/iOSInterviewQuestions 以及 http://www.90159.com/2015/07/26/71/ 還有 http://www.jianshu.com/p/4fea8fa60d75 。不過網路上的答案終究是別人的,唯有實實在在的自己研究過一遍,才會成為自己的東西,共勉之。

下面是一些我蒐集的基本觀念文章,也許可以幫你節省一點找資料的時間。

Property

http://www.devtalking.com/articles/you-should-to-know-property/

Block

http://www.devtalking.com/articles/you-should-know-block/

物件之間的溝通

https://www.objc.io/issues/7-foundation/communication-patterns/

Category

http://tech.meituan.com/DiveIntoCategory.html

KVC, KVO

http://objccn.io/issue-7-3/
http://southpeak.github.io/blog/2015/04/23/nskeyvalueobserving-kvo/

Runloop

http://blog.ibireme.com/2015/05/18/runloop/

Deep copy & Shallow copy

https://www.zybuluo.com/MicroCai/note/50592

Runtime

http://blog.eddie.com.tw/2013/12/05/object-class-and-meta-class-in-objective-c/
http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/
http://chun.tips/blog/categories/objective-c-runtime/
http://southpeak.github.io/blog/2014/10/25/objective-c-runtime-yun-xing-shi-zhi-lei-yu-dui-xiang/

ARC釋放機制

http://blog.sunnyxx.com/2014/04/02/objc_dig_arc_dealloc/

Autorelease原理

http://blog.sunnyxx.com/2014/10/15/behind-autorelease/

Method swizzling

http://southpeak.github.io/blog/2014/11/06/objective-c-runtime-yun-xing-shi-zhi-si-:method-swizzling/

2015年8月11日 星期二

Mock completion block with OCMock

This is an example unit test using Specta, Expecta and OCMock.
Another example - WordPress iOS app unit test.

#import "Specta.h"
#define EXP_SHORTHAND
#import "Expecta.h"
#import <OCMock/OCMock.h>
#import "RoomListViewModel.h"
#import <EXTScope.h>

SpecBegin(RoomListViewModel)

describe(@"RoomListViewModel", ^{

    __block RoomListViewModel *viewModel;
    __block id home;
    __block id room;

    beforeAll(^{

    });

    beforeEach(^{
        home = OCMClassMock([HMHome class]);
        room = OCMClassMock([HMRoom class]);
        viewModel = [[RoomListViewModel alloc] initWithHome:home];
    });

    it(@"add room with name", ^{
        OCMStub([home addRoomWithName:OCMOCK_ANY completionHandler:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) {
            void(^ __unsafe_unretained completionHandler)(HMRoom *room, NSError *error);
            [invocation getArgument:&completionHandler atIndex:3];
            completionHandler(room, nil);
        });    
        waitUntil(^(DoneCallback done) {
            @weakify(viewModel);
            [viewModel addRoomWithName:@"test" completionHandler:^(NSError *error) {
                @strongify(viewModel);
                expect(...);
                done();
            }];
        });

    });  

    afterEach(^{
        viewModel = nil;
    });

    afterAll(^{

    });
});

SpecEnd
void(^ __unsafe_unretained completionHandler)(HMRoom *room, NSError *error);

Why declare our block __unsafe_unretained?
See http://stackoverflow.com/a/13831074/1060971, Carl Lindberg’s comment.

[invocation getArgument:&completionHandler atIndex:3];

In NSInvocation, argument index 0 is self , index 1 is cmd.
First argument of addRoomWithName is at index 2, completion block argument is at index 3.
So, assign our mock block at index 3.

2015年8月6日 星期四

Xcode6 + Swift 1.2 Podfile

Swift 1.2 + RAC3

platform :ios, "8.0"
use_frameworks!

pod "ReactiveCocoa", '3.0-RC.1'

target :MyAppTests, :exclusive => true do
  pod 'Quick', '0.3.1'
  pod 'Nimble', '1.0.0'
end

2015年7月22日 星期三

在Mac下開發MP4的相關資源

簡介

MP4只是一種container,可以想像成容器,裡面可以放mp3或aac等音樂。
關於MP4格式的spec可以在這裡下載。

Library

關於MP4檔案的操作,已經有現成的library可以使用囉~
https://code.google.com/p/mp4v2/

觀察MP4格式的工具

可以藉由atomicparsley這個工具來印出MP4檔案的內部結構

brew install atomicparsley
atomicparsley /path/to/mp4 -T 1

印出來的結果像這樣

Atom ftyp @ 0 of size: 24, ends @ 24
Atom moov @ 24 of size: 569, ends @ 593
     Atom mvhd @ 32 of size: 108, ends @ 140
     Atom iods @ 140 of size: 24, ends @ 164
     Atom trak @ 164 of size: 429, ends @ 593
         Atom tkhd @ 172 of size: 92, ends @ 264
         Atom mdia @ 264 of size: 329, ends @ 593
             Atom mdhd @ 272 of size: 32, ends @ 304
             Atom hdlr @ 304 of size: 33, ends @ 337
             Atom minf @ 337 of size: 256, ends @ 593
                 Atom smhd @ 345 of size: 16, ends @ 361
                 Atom dinf @ 361 of size: 36, ends @ 397
                     Atom dref @ 369 of size: 28, ends @ 397
                         Atom url  @ 385 of size: 12, ends @ 397
                 Atom stbl @ 397 of size: 196, ends @ 593
                     Atom stsd @ 405 of size: 96, ends @ 501
                         Atom mp4a @ 421 of size: 80, ends @ 501
                             Atom esds @ 457 of size: 44, ends @ 501
                     Atom stts @ 501 of size: 24, ends @ 525
                     Atom stsz @ 525 of size: 20, ends @ 545
                     Atom stsc @ 545 of size: 28, ends @ 573
                     Atom stco @ 573 of size: 20, ends @ 593
Atom mdat @ 593 of size: 9, ends @ 602
------------------------------------------------------
Total size: 602 bytes; 22 atoms total.
Media data: 0 bytes; 602 bytes all other atoms (100.000% atom overhead).
Total free atom space: 0 bytes; 0.000% waste.
------------------------------------------------------
AtomicParsley version: 0.9.6 (utf8)
------------------------------------------------------
Movie duration: 7504.597 seconds (02:05:04.60) - 0.00* kbp/sec bitrate (*=approximate)
Low-level details. Total tracks: 1
Trk  Type  Handler                    Kind  Lang  Bytes
1    soun  [none listed]              mp4a  und   1
     0.00* kbp/s  7504.597 sec  MPEG-4 Unknown profile: 0x0    channels: (2)

這個用python寫的工具也是不錯的選擇
https://github.com/amarghosh/mp4viewer
mp4Viewer

2015年3月10日 星期二

讓Alcatraz支援Xcode 6.2

  1. 打開Finder,跳到~/Library/Application Support/Developer/Shared/Xcode/Plug-ins
  2. 右鍵點plugin,顯示套件內容
  3. 打開Info.plist
  4. 在DVTPlugInCompatibilityUUIDs的Array加入A16FF353-8441-459E-A50C-B071F53F51B7
  5. 重啟Xcode

參考:https://github.com/supermarin/Alcatraz/issues/218