KISS

Be Among the 20% of the Best!

Objective-C: Weird Retain Cycle Warning

| comments

I was writing unit tests for an iOS project recently when I stumbled upon a very weird issue with a retain cycle warning from Clang. I created a minimal sample file to demonstrate it:

(retain_cycle_sample.m) download
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//
//  main.m
//  RetainCycleWarning
//
//  Created by u on 2015-04-04.
//  Copyright (c) 2015 yes. All rights reserved.
//

#import <Foundation/Foundation.h>
@import XCTest;


@interface Foo : NSObject

typedef void (^SuccessBlock)(CGFloat value);

- (void)setValue:(CGFloat)value
         success:(SuccessBlock)success;
- (void)getValueWithSuccessBlock:(SuccessBlock)success;

@end

@implementation Foo

- (void)setValue:(CGFloat)value
          success:(SuccessBlock)success {
}

- (void)getValueWithSuccessBlock:(SuccessBlock)success {
}

@end



@interface mainTests : XCTestCase

// used in multiple tests
@property (nonatomic, strong) Foo *foo;

@end

@implementation mainTests

- (void)setUp {
    [super setUp];
    self.foo = [Foo new];
}

- (void)tearDown {
    self.foo = nil;
    [super tearDown];
}

- (void)testFoo {
    [self.foo getValueWithSuccessBlock:^(CGFloat value) {
        XCTFail(@"success");
    }];

    [self.foo setValue:1.0
               success:^(CGFloat value) {
                   XCTFail(@"success");
               }];
}

@end



int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
    }
    return 0;
}

It’s the only file in a OS X command-line tool project. It has the Foo class with two simple methods to get and set a value, with empty implementations. Then, in a test class I create a property for a Foo object (because it’s originally used in multiple test methods), and test that the success blocks are not called. You don’t need to run the tests, because the point is this warning while building:

1
2
3
4
5
6
7
8
9
10
11
CompileC Library/Developer/Xcode/DerivedData/RetainCycleWarning-x/Build/Intermediates/RetainCycleWarning.build/Debug/RetainCycleWarning.build/Objects-normal/x86_64/main.o RetainCycleWarning/main.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
// …

RetainCycleWarning/RetainCycleWarning/main.m:62:20: warning: capturing 'self' strongly in this block is likely to lead to a retain cycle [-Warc-retain-cycles]
                   XCTFail(@"success");
                   ^~~~~~~~~~~~~~~~~~~
// …
RetainCycleWarning/RetainCycleWarning/main.m:60:6: note: block will be retained by an object strongly retained by the captured object
    [self.foo setValue:1.0
     ^~~~
1 warning generated.

Only one warning even though the get and set tests are the same — just calling XCTFail() in a success block.

Jenkins Clang Scan-Build Plugin: Support Matrix Builds

| comments

I’m using Jenkins to build iOS projects (as you may have noticed from my previous jenkins posts). One of build steps that can help developers is running the Clang scan-build static analyzer and publishing the results. Luckily, there is an existing Clang Scan-Build Jenkins plugin available, however it hasn’t been updated for a while. I stumbled upon Sean Wang’s blog post (https://fclef.wordpress.com/2014/10/11/jenkins-clang-scan-build-plugin-support-for-xcode5-and-later/) describing his fixes for latest Xcode. That’s a great update!

So it worked fine until I needed to use it in a matrix (aka multi-configuration) project. It was missing from the list of available build steps! One solution is to emulate the matrix build by having N regular builds, one for each of the configurations, to run the analyzer, but that would be very painful to maintain.

Jenkins Doesn’t Run as a LaunchAgent?

| comments

If you are interested in Jenkins and followed my post about setting it up in a virtual machine, you should be totally fine. However, when I was messing with it, I had an issue when the jenkins agent wouldn’t start:

1
2
3
launchctl load ~/Library/LaunchAgents/org.jenkins-ci.plist
launchctl load ~/Library/LaunchAgents/org.jenkins-ci.plist
/Users/Shared/Jenkins/Library/LaunchAgents/org.jenkins-ci.plist: Operation already in progress

Jenkins: Admin Is Missing the Overall/Read Permission

| comments

I stumbled upon this issue recently: somebody has created an admin user in a fresh Jenkins installation (most likely, through the normal Jenkins interface). However, after a few days, they couldn’t login as the admin, seeing this error:

admin is missing the Overall/Read permission

Sync Time in VirtualBox OS X Guest

| comments

Virtualization is great! It allows me to mess up with my Jenkins setup trying to figure out how to configure iOS jobs with tests (jumping through a number of hoops on the way, hi Apple!). One point though is that the guest OS X in VirtualBox has terribly slow graphics, and also freezes after some time. Only restart helps. Hopefully, I usually need ssh and jenkins web interface only. Read about how to set that up here: Jenkins in OSX guest in VirtualBox for iOS jobs – full setup guide.

Anyway, due to missing VBox additions on OSX guest, time doesn’t update when the machine is suspended and then resumed. Plus, there is a constant time drift. Explanations here: https://forums.virtualbox.org/viewtopic.php?f=22&t=48233.

Jenkins in OSX Guest in VirtualBox for iOS Jobs – Full Setup Guide

| comments

Hello there!

Updated on 2015-04-18: added a simple command to allow web update.

In this post, I will describe how to setup a sandboxed Jenkins server in a virtual machine where you can play and try your iOS (and not only) jobs. I’m using the latest OS X Yosemite 10.10.2 for the host and the guest on a MacBook Pro. Nota Bene: according to the Apple’s EULA for OS X, you are allowed to run the OS on the Apple hardware only.

This how-to assumes you know what a command-line is, how to run commands, and related stuff.