Senior Mobile Developer - Vale

Contact me via @cwtututu.


  • Home

  • Categories

  • Archives

  • Tags

  • About

Avoid Retain Cycle in Block

Posted on Apr 10 2013   |   In GCD   |  

Let us make long story short. Please see the codes as following:

- (IBAction)didTapUploadButton:(id)sender
{
  NSString *clientID = @"YOUR_CLIENT_ID_HERE";

  NSString *title = [[self titleTextField] text];
  NSString *description = [[self descriptionTextField] text];

  [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

  __weak MLViewController *weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImage *image = [UIImage imageNamed:@"balloons.jpg"];
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0f);

[MLIMGURUploader uploadPhoto:imageData 
                       title:title 
                 description:description 
               imgurClientID:clientID completionBlock:^(NSString *result) {
  dispatch_async(dispatch_get_main_queue(), ^{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    [[weakSelf linkTextView] setText:result];
  });
} failureBlock:^(NSURLResponse *response, NSError *error, NSInteger status) {
  dispatch_async(dispatch_get_main_queue(), ^{
  [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
  [[[UIAlertView alloc] initWithTitle:@"Upload Failed"
                              message:[NSString stringWithFormat:@"%@ (Status code %d)", 
                                               [error localizedDescription], status]
                             delegate:nil
                    cancelButtonTitle:nil
                    otherButtonTitles:@"OK", nil] show];
  });
}];

  });
}

This is a method for uploading images to imgur. In the section we can find the codes __weak MLViewController *weakSelf = self; and use it like [[weakSelf linkTextView] setText:result];. So, we have a question: Why we don‘t call self directly,but rather give a weak pointer to point it and use the weak pointer in the block section?

It is what i will say. As we all know, the property of blocks is copy, and the property of self is retain. So, if we use self in the block section, we will get a retain circle. We will never release them. For this reason, we need do it as above.

Here is one reference

Ok, Good night. See you.

How to Customize the UI of MPMoviePlayerViewController

Posted on Apr 6 2013   |   In MPMoviePlayerViewController   |  

As we all know, the user interface of MPMoviePlayerViewController is ugly. Sometimes, our customer needs a better UI, so let’s do it.

Some codes like this:

MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] init];
    player.moviePlayer.contentURL = self.url;
    //here, i set the controlStyle equal to MPMovieControlStyleNone, as a result, we only see the movie view, yet volume button, progress slider, play button as so on.
    player.moviePlayer.controlStyle = MPMovieControlStyleNone;
    player.moviePlayer.view.frame = self.playerViewController.view.frame;
    //next, i create a UIViewController named playerViewController, and insert the moverPlay view to the view of playerViewController.
    [self.playerViewController.view insertSubview:player.moviePlayer.view atIndex:0];
    [player.moviePlayer play];
    [self presentModalViewController:self.playerViewController animated:YES];

after do that, we need add a view to playerViewController, and set the view is transparent , we can add custom button on the view to control the move playing. The effect as below:

Screenshot 2013.04.03 09.32.26

How to Learn to Cattle Men

Posted on Apr 6 2013   |   In Life   |  

修行之道:

关注大师的言行,

跟随大师的举动,

和大师一并修行,

领会大师的意境,

成为真正的大师。

Some Advice About Using ARC

Posted on Mar 31 2013   |   In ARC   |  
  1. As long as there is a variable pointing to an object, that object stay in memory. When the pointer gets a new value or ceases to exist, the associated object is released.This is true for all variables:instance variables,synthesized properties, adn even local variables.
  2. “weak” pointer. Variables that are weak can still point to objects but they do not become owners.
  3. Please change the Complier for C/C++/Object-c option to Apple LLVM compiler 3.0.
  4. Please set Other Waring Flags option to -Wall.
  5. Please set Run Static Analyzer option to Yes.
  6. Please set Objective-c Automatic Reference Counting option to Yes.
  7. Some files needn’t to convert to ARC support, use the -fno-objc-arc flag.
  8. You will get this error when your code does the following:

    switch (X)
    {    
        case Y:
            NSString *s = ...;
            break;
    }
    

    you need do this:

    switch (X)
    {    
       case Y:
       {
           NSString *s = ...;
           break;
       }
    }
    
  9. If instace variables are a part of the internals of your class and not something you want expose in its public interface. you can move the instace variables from interface section to implementation section. some codes from .h file as following:

    #import <UIKit/UIKit.h>

    @interface MainViewController : UIViewController 
      <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, 
      NSXMLParserDelegate>

    @property (nonatomic, retain) IBOutlet UITableView *tableView;
    @property (nonatomic, retain) IBOutlet UISearchBar *searchBar;

    @end

move the instace variables to implementation section as following:


    @implementation MainViewController
    {
        NSOperationQueue *queue;
        NSMutableString *currentStringValue;
    }
  1. Generally, dealloc method isn’t need.The only reason for keeping a dealloc method around is when you need to free certain resources that do not fall under ARC’s umbrella. Examples of this are calling CFRelease() on Core Foundation objects, calling free() on memory that you allocated with malloc(), unregistering for notifications, invalidating a timer, and so on.
  2. Toll-Free Bridging

    Change ownership from Core Foundation to Objecttive-C, use CFBridgingRelease().

    Change ownership from Objective-C to Core Foundation, use CFBridgingRetain().

    Want to use one type temporarily as if it were another without owership change, use __bridge.

Use Command Line to Pack Applications

Posted on Mar 30 2013   |   In Utility   |  

All right. It is time for me to write something. My wife has stayed in her hometown about half a month. I miss her very much. It is dark out of the window. You know, in summer, the rain is rich in ShenZhen. Sometimes, I am very anxious about doing something which is matter with opportunity and ability. Anyway, let us do something about work.

Sometimes we need to build apps for many channels, we needn’t change many codes but some configurations. As we all know, we use Xcode to build and run application. many channels many building. So boring! So let us see how to do it using command line.

  • first shell, it is used for generating binary to upload AppStore.

    #!/bin/sh
    target="Power7 MobileView"
    distDir="/Users/tuchangwei/Documents/WorkSpace/Release/${factory}/${appName}_V${version}"
    rm -rdf "$distDir"
    mkdir "$distDir"
    
    uploadDir="${distDir}/Upload AppStore"
    rm -rdf "$uploadDir"
    mkdir "$uploadDir"
    /usr/bin/xcodebuild -target "$target" clean
    echo "******************start build*********************"
    /usr/bin/xcodebuild -target "$target" CODE_SIGN_IDENTITY="$distribution"
    echo "******************start pick .ipa*********************"
    /usr/bin/xcrun -sdk iphoneos PackageApplication -v build/Release-iphoneos/*.app -o "${uploadDir}/${appName}.ipa" --sign "$distribution"
    echo "******************start pick test .ipa*********************"
    codesign -f --sign "iPhone Developer: Nelson Chen (JPMGJWJFAQ)" build/Release-iphoneos/*.app
    /usr/bin/xcrun -sdk iphoneos PackageApplication -v build/Release-iphoneos/*.app -o "${distDir}/${appName}_V${version}.ipa" --sign "iPhone Developer: Nelson Chen (JPMGJWJFAQ)" --embed "/Users/tuchangwei/Library/MobileDevice/Provisioning Profiles/D788EEA0-848E-4F5E-AA30-87D38154DA9B.mobileprovision"
    
  • second shell is used for generating test binary

    #!/bin/sh
    target="Power7 MobileView"
    distDir="/Users/tuchangwei/Desktop/Test"
    rm -rdf "$distDir"
    mkdir "$distDir"
    /usr/bin/xcodebuild -target "$target" clean
    echo "******************start build*********************"
    /usr/bin/xcodebuild -target "$target" 
    echo "******************start pick test .ipa*********************"
    codesign -f --sign "iPhone Developer: Nelson Chen (JPMGJWJFAQ)" build/Release-iphoneos/*.app
    /usr/bin/xcrun -sdk iphoneos PackageApplication -v build/Release-iphoneos/*.app -o "${distDir}/test.ipa" --sign "iPhone Developer: Nelson Chen (JPMGJWJFAQ)" --embed "/Users/tuchangwei/Library/MobileDevice/Provisioning Profiles/D788EEA0-848E-4F5E-AA30-87D38154DA9B.mobileprovision"
    
  • third shell is used for deleting .svn files in project.

    #!/bin/sh
    echo "start delete .svn..."
    find $PWD/ -name .svn -print0 | xargs -0 rm -rf
    echo "finish delete .svn."
    

So, you know, i also use some shell to improve efficiency. See you,O(∩_∩)O~.

Terminal Shortcuts

Posted on Mar 30 2013   |   In Utility   |  

###mac/linux终端光标的快捷键操作

####常用的快捷键:

  • Ctrl + d 删除一个字符,相当于通常的Delete键(命令行若无所有字符,则相当于exit;处理多行标准输入时也表示eof)
  • Ctrl + h 退格删除一个字符,相当于通常的Backspace键
  • Ctrl + u 删除光标之前到行首的字符
  • Ctrl + k 删除光标之前到行尾的字符
  • Ctrl + c 取消当前行输入的命令,相当于Ctrl + Break
  • Ctrl + a 光标移动到行首(Ahead of line),相当于通常的Home键
  • Ctrl + e 光标移动到行尾(End of line)
  • Ctrl + f 光标向前(Forward)移动一个字符位置
  • Ctrl + b 光标往回(Backward)移动一个字符位置
  • Ctrl + l 清屏,相当于执行clear命令
  • Ctrl + p 调出命令历史中的前一条(Previous)命令,相当于通常的上箭头
  • Ctrl + n 调出命令历史中的下一条(Next)命令,相当于通常的上箭头
  • Ctrl + r 显示:号提示,根据用户输入查找相关历史命令(reverse-i-search)

####次常用快捷键:

  • Alt + f 光标向前(Forward)移动到下一个单词
  • Alt + b 光标往回(Backward)移动到前一个单词
  • Ctrl + w 删除从光标位置前到当前所处单词(Word)的开头
  • Alt + d 删除从光标位置到当前所处单词的末尾
  • Ctrl + y 粘贴最后一次被删除的单词

以上就是快捷键了,在这里我只想揭露一些事情,这些快捷键都是emacs的快捷键!熟悉终端的同学应该知道,终端里可以设置快捷键的类型是vim还是emacs。当然了大多数的终端都用的emacs,因为啥自己想去吧。

在这里之所以又将这些东西提出来的原因是:mac os x虽然是图形界面,但是chrome,xcode啥的也支持这些快捷键!

摘自:http://blog.cnrainbird.com/index.php/2012/03/23/mac_linux_zhong_duan_guang_biao_de_kuai_jie_jian_cao_zuo/

How Should We Use NSLog

Posted on Mar 26 2013   |   In NSLog   |  

As we all know, every programming language has a selector to print the value on the Console which we want to. This way to debug is too violence, too simple and underestimated by someone. Other way is setting breakpoints, after application runs, it will stop when meets a breakpoint. Someone like this way, he need not see the Console and restart the application again and again to print.

But i want to say, unitl now, i really have been tend to print value. Because when some mulitithreadings run at the same time, it is difficult to track the breakpoint. However other way is easy just as “History don’t lie”. We can print the system time,the line of printing, the selector, the value of some object,the class as so on.

So,let us see the follow codes.

#if DEBUG
#define NSLog(FORMAT, ...) {\
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];\
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];\
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];\
[dateFormatter setDateFormat:@"HH:mm:ss:SSSSSS"]; \
NSString *str = [dateFormatter stringFromDate:[NSDate date]];\
[dateFormatter release];\
fprintf(stderr,"[--%s--]*[--%s--]*[--%s:%d--]\n",[str UTF8String],     [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String],[[[NSString     stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__);\
}
#else
#define NSLog(FORMAT, ...) nil
#endif 

This is a macro definition. You can copy this to your CommonHead.h file and import the CommonHead.h to your .pch file so that you can use it at anywhere in your project. The macrodefinition is great, when you use debug mode to print value, you will find the value, the system time, the line and the object where the selector in, yet using the release mode, you will see nothing. The reason is as follow:

0F804C40-EA0B-42C5-8058-7E3230E01A13

Why we need print the line of the selector? Yes, you guess it, press “cmd” + “i” when using Xcode, you will find the selector right now!

Use Block to Call Back Instead of Delegate

Posted on Mar 21 2013   |   In GCD   |  

Some days ago, i posted the blog to introduce some ways to talk to each oher between Object A and B. One of the points is Blocks. Now I will show how to call back use Block instead of Delegate.

Some codes posted as follow:

A:SWDPromptViewController

.h
//declare a block named "dismissPromptViewBlock".
@property (copy, nonatomic) void(^dismissPromptViewBlock)    (SWDPromptViewController *prompt);

.m
//after some operations, we will dismiss A and release it.
-(void)dismissPrompt
{
    if (self.dismissPromptViewBlock)
    {
        self.dismissPromptViewBlock(self);
        self.dismissPromptViewBlock = nil;
    }
}


B:
.m
//declare A object and init it,then assign a block to the property of A.
//so when A executes the method "dismissPrompt", the block plays a part of
//Delegate.
SWDPromptViewController *promptViewController = [[SWDPromptViewController     alloc] initWithNibName:@"SWDPromptViewController" bundle:nil type:type];
UIWindow *promptWindow = [[UIWindow alloc] initWithFrame:[[UIScreen     mainScreen] bounds]];
promptWindow.windowLevel = UIWindowLevelAlert;
promptWindow.backgroundColor = [UIColor clearColor];
promptWindow.rootViewController = promptViewController;
[promptViewController release];
[promptWindow makeKeyAndVisible];

promptViewController.dismissPromptViewBlock = ^(SWDPromptViewController     *prompt){

    [promptWindow release];
    };

That is all. Welcome to communicate with me.O(∩_∩)O~.

从Nib加载View(loading View From Nib)

Posted on Mar 19 2013   |   In nib   |  

话说,有些View界面控件比较多,还是用nib拖拖拉拉方便。但是麻烦的一点是,我们要将nib与View对应的类进行连接,然后使用这个View的地方通过nib进行对象反序列化。我们一般用下面的语句进行反对象序列化。

self.aboutView = [[[NSBundle mainBundle]loadNibNamed:@"AboutView" owner:self options:nil] objectAtIndex:0];
[self.view addSubview:self.aboutView];

每次都写如上的代码有些麻烦,其实我们可以为UIView创建一个category:

@implementation UIView (MHExtensions)

+ (id)mh_viewFromNibNamed:(NSString *)nibName owner:(id)ownerOrNil
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibName owner:ownerOrNil options:nil];
    for (id object in nib)
    {
        if ([object isKindOfClass:[self class]])
            return object;
    }
    return nil;
}

@end

这样每次反序列化就只需要调用 + (id)mh_viewFromNibNamed:(NSString *)nibName owner:(id)ownerOrNil 这个方法即可。

对象传值的几种方式(Some Methods to Make Talk to Each Other Between Objects a and B)

Posted on Mar 19 2013   |   In Summary   |  
  1. NSNotificationCenter. This is anonymous one-to-many communication. Object A posts a notification to the NSNotificationCenter, which then distributes it to any other objects listening for that notification, including Object B. A and B do not have to know anything about each other, so this is a very loose coupling. Maybe a little too loose…
  2. KVO (Key-Value Observing). One object observes the properties of another. This is a very tight coupling, because Object B is now peeking directly into Object A. The advantage of KVO is that Object A doesn’t have to be aware of this at all, and therefore does not need to send out any notifications — the KVO mechanism takes care of this behind the scenes.
  3. Direct pointers. Object A has a pointer to Object B and directly sends it messages when something of interest happens. This is the tightest coupling possible because A and B cannot function without each other. In the case of view controllers you generally want to avoid this.
  4. Delegates. Object B is a delegate of Object A. In this scenario, Object A does not know anything about Object B. It just knows that some object performs the role of its delegate and it will happily send messages to that delegate, but it doesn’t know — or care — that this is Object B. The delegate pattern is often the preferred way to communicate between view controllers, but it takes some work to set up.
  5. Blocks. Essentially the same approach as delegates, except that Object B now gives Object A one or more blocks (closures) to be executed when certain events take place. There is no formal delegate protocol and the only thing that Object A sees of Object B is the blocks it is given.

话说KVO检测对象的属性和Blocks相互传值还没使用过,回头试一下。

1…678
Changwei

Changwei

I develop iOS/Android apps with Swift/Kotlin language.

80 posts
33 categories
34 tags
GitHub Twitter Weibo Linkedin Upwork peopleperhour
Creative Commons
© 2011 - 2020 Changwei
Powered by Hexo
Theme - NexT.Muse