Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -420,15 +420,20 @@ } objc_autoreleasePoolPop(pool); } } else { + bool first = true; + for (id object in self) { void *pool = objc_autoreleasePoolPush(); - if ([ret length] > 0) + if OF_UNLIKELY (first) + first = false; + else [ret appendString: separator]; + [ret appendString: [object performSelector: selector]]; objc_autoreleasePoolPop(pool); } } Index: tests/OFArrayTests.m ================================================================== --- tests/OFArrayTests.m +++ tests/OFArrayTests.m @@ -162,12 +162,12 @@ EXPECT_EXCEPTION(@"Detect out of range in -[removeObjectsInRange:]", OFOutOfRangeException, [m[0] removeObjectsInRange: of_range(0, [m[0] count] + 1)]) TEST(@"-[componentsJoinedByString:]", - (a[1] = [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil]) && - [[a[1] componentsJoinedByString: @" "] isEqual: @"foo bar baz"] && + (a[1] = [OFArray arrayWithObjects: @"", @"a", @"b", @"c", nil]) && + [[a[1] componentsJoinedByString: @" "] isEqual: @" a b c"] && (a[1] = [OFArray arrayWithObject: @"foo"]) && [[a[1] componentsJoinedByString: @" "] isEqual: @"foo"]) TEST(@"-[componentsJoinedByString:options]", (a[1] = [OFArray arrayWithObjects: @"", @"foo", @"", @"", @"bar",